Kamil Dudka 8d9eac
diff --git a/src/expand-common.c b/src/expand-common.c
Kamil Dudka 8d9eac
index 4657e46..97cbb09 100644
Kamil Dudka 8d9eac
--- a/src/expand-common.c
Kamil Dudka 8d9eac
+++ b/src/expand-common.c
Jakub Martisko 0a63fa
@@ -18,6 +18,7 @@
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
 #include <stdio.h>
Jakub Martisko 0a63fa
 #include <sys/types.h>
Jakub Martisko 0a63fa
+#include <mbfile.h>
Jakub Martisko 0a63fa
 #include "system.h"
Kamil Dudka 8d9eac
 #include "die.h"
Jakub Martisko 0a63fa
 #include "error.h"
Kamil Dudka 8d9eac
@@ -85,6 +86,119 @@ add_tab_stop (uintmax_t tabval)
Kamil Dudka 8d9eac
     }
Kamil Dudka 8d9eac
 }
Jakub Martisko 0a63fa
 
Kamil Dudka 8d9eac
+extern int
Jakub Martisko 0a63fa
+set_utf_locale (void)
Jakub Martisko 0a63fa
+{
Jakub Martisko 0a63fa
+      /*try using some predefined locale */
Jakub Martisko 0a63fa
+      const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"};
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+      const int predef_locales_count=3;
Jakub Martisko 0a63fa
+      for (int i=0;i
Jakub Martisko 0a63fa
+        {
Jakub Martisko 0a63fa
+          if (setlocale(LC_ALL,predef_locales[i])!=NULL)
Jakub Martisko 0a63fa
+          {
Jakub Martisko 0a63fa
+            break;
Jakub Martisko 0a63fa
+          }
Jakub Martisko 0a63fa
+          else if (i==predef_locales_count-1)
Jakub Martisko 0a63fa
+          {
Jakub Martisko 0a63fa
+            return 1;
Jakub Martisko 0a63fa
+            error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
Jakub Martisko 0a63fa
+          }
Jakub Martisko 0a63fa
+        }
Jakub Martisko 0a63fa
+        return 0;
Jakub Martisko 0a63fa
+}
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+extern bool
Jakub Martisko 0a63fa
+check_utf_locale(void)
Jakub Martisko 0a63fa
+{
Jakub Martisko 0a63fa
+  char* locale = setlocale (LC_CTYPE , NULL);
Jakub Martisko 0a63fa
+  if (locale == NULL) 
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    return false;
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  else if (strcasestr(locale, "utf8") == NULL && strcasestr(locale, "utf-8") == NULL)
Jakub Martisko 0a63fa
+  { 
Jakub Martisko 0a63fa
+    return false;
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  return true;
Jakub Martisko 0a63fa
+}
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+extern bool
Jakub Martisko 0a63fa
+check_bom(FILE* fp, mb_file_t *mbf)
Jakub Martisko 0a63fa
+{
Jakub Martisko 0a63fa
+  int c;
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+  c=fgetc(fp);
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+  /*test BOM header of the first file */
Jakub Martisko 0a63fa
+  mbf->bufcount=0;
Jakub Martisko 0a63fa
+  if (c == 0xEF)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    c=fgetc(fp);
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  else
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    if (c != EOF)
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      ungetc(c,fp);
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+    return false;
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+  if (c == 0xBB)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    c=fgetc(fp);
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  else
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    if ( c!= EOF )
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      mbf->buf[0]=(unsigned char) 0xEF;
Jakub Martisko 0a63fa
+      mbf->bufcount=1;
Jakub Martisko 0a63fa
+      ungetc(c,fp);
Jakub Martisko 0a63fa
+      return false;
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+    else
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      ungetc(0xEF,fp);
Jakub Martisko 0a63fa
+      return false;
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  if (c == 0xBF)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    mbf->bufcount=0;
Jakub Martisko 0a63fa
+    return true;
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  else
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    if (c != EOF)
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      mbf->buf[0]=(unsigned char) 0xEF;
Jakub Martisko 0a63fa
+      mbf->buf[1]=(unsigned char) 0xBB;
Jakub Martisko 0a63fa
+      mbf->bufcount=2;
Jakub Martisko 0a63fa
+      ungetc(c,fp);
Jakub Martisko 0a63fa
+      return false;
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+    else
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      mbf->buf[0]=(unsigned char) 0xEF;
Jakub Martisko 0a63fa
+      mbf->bufcount=1;
Jakub Martisko 0a63fa
+      ungetc(0xBB,fp);
Jakub Martisko 0a63fa
+      return false;
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+  return false;
Jakub Martisko 0a63fa
+}
Jakub Martisko 0a63fa
+
Kamil Dudka 8d9eac
+extern void
Jakub Martisko 0a63fa
+print_bom(void)
Jakub Martisko 0a63fa
+{
Jakub Martisko 0a63fa
+  putc (0xEF, stdout);
Jakub Martisko 0a63fa
+  putc (0xBB, stdout);
Jakub Martisko 0a63fa
+  putc (0xBF, stdout);
Jakub Martisko 0a63fa
+}
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
 /* Add the comma or blank separated list of tab stops STOPS
Jakub Martisko 0a63fa
    to the list of tab stops.  */
Kamil Dudka 8d9eac
 extern void
Kamil Dudka 8d9eac
diff --git a/src/expand-common.h b/src/expand-common.h
Kamil Dudka 8d9eac
index 8cb2079..763bfda 100644
Kamil Dudka 8d9eac
--- a/src/expand-common.h
Kamil Dudka 8d9eac
+++ b/src/expand-common.h
Kamil Dudka 8d9eac
@@ -34,6 +34,18 @@ extern size_t max_column_width;
Kamil Dudka 8d9eac
 /* The desired exit status.  */
Kamil Dudka 8d9eac
 extern int exit_status;
Jakub Martisko 0a63fa
 
Kamil Dudka 8d9eac
+extern int
Jakub Martisko 0a63fa
+set_utf_locale (void);
Jakub Martisko 0a63fa
+
Kamil Dudka 8d9eac
+extern bool
Jakub Martisko 0a63fa
+check_utf_locale(void);
Jakub Martisko 0a63fa
+
Kamil Dudka 8d9eac
+extern bool
Jakub Martisko 0a63fa
+check_bom(FILE* fp, mb_file_t *mbf);
Jakub Martisko 0a63fa
+
Kamil Dudka 8d9eac
+extern void 
Jakub Martisko 0a63fa
+print_bom(void);
Jakub Martisko 0a63fa
+
Kamil Dudka 8d9eac
 /* Add tab stop TABVAL to the end of 'tab_list'.  */
Kamil Dudka 8d9eac
 extern void
Kamil Dudka 8d9eac
 add_tab_stop (uintmax_t tabval);
Kamil Dudka 8d9eac
diff --git a/src/expand.c b/src/expand.c
Kamil Dudka 8d9eac
index 310b349..4136824 100644
Kamil Dudka 8d9eac
--- a/src/expand.c
Kamil Dudka 8d9eac
+++ b/src/expand.c
Kamil Dudka 8d9eac
@@ -105,11 +105,33 @@ expand (void)
Jakub Martisko 0a63fa
   FILE *fp = next_file (NULL);
Jakub Martisko 0a63fa
   mb_file_t mbf;
Jakub Martisko 0a63fa
   mbf_char_t c;
Jakub Martisko 0a63fa
-
Jakub Martisko 0a63fa
+  /* True if the starting locale is utf8.  */
Jakub Martisko 0a63fa
+  bool using_utf_locale;
Jakub Martisko 0a63fa
+ 
Jakub Martisko 0a63fa
+  /* True if the first file contains BOM header.  */
Jakub Martisko 0a63fa
+  bool found_bom;
Jakub Martisko 0a63fa
+  using_utf_locale=check_utf_locale();
Jakub Martisko 0a63fa
+  
Jakub Martisko 0a63fa
   if (!fp)
Jakub Martisko 0a63fa
     return;
Jakub Martisko 0a63fa
-
Jakub Martisko 0a63fa
   mbf_init (mbf, fp);
Jakub Martisko 0a63fa
+  found_bom=check_bom(fp,&mbf);
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+  if (using_utf_locale == false && found_bom == true)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    /*try using some predefined locale */
Jakub Martisko 0a63fa
+    
Jakub Martisko 0a63fa
+    if (set_utf_locale () != 0)
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
+ 
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+  if (found_bom == true)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    print_bom();
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
   while (true)
Jakub Martisko 0a63fa
     {
Kamil Dudka 8d9eac
@@ -134,6 +156,27 @@ expand (void)
Jakub Martisko 0a63fa
             if ((mb_iseof (c)) && (fp = next_file (fp)))
Jakub Martisko 0a63fa
               {
Jakub Martisko 0a63fa
                 mbf_init (mbf, fp);
Jakub Martisko 0a63fa
+                if (fp!=NULL)
Jakub Martisko 0a63fa
+                {
Jakub Martisko 0a63fa
+                  if (check_bom(fp,&mbf)==true)
Jakub Martisko 0a63fa
+                  {
Jakub Martisko 0a63fa
+                    /*Not the first file - check BOM header*/
Jakub Martisko 0a63fa
+                    if (using_utf_locale==false && found_bom==false)
Jakub Martisko 0a63fa
+                    {
Jakub Martisko 0a63fa
+                      /*BOM header in subsequent file but not in the first one. */
Jakub Martisko 0a63fa
+                      error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
Jakub Martisko 0a63fa
+                    }
Jakub Martisko 0a63fa
+                  }
Jakub Martisko 0a63fa
+                  else
Jakub Martisko 0a63fa
+                  {
Jakub Martisko 0a63fa
+                    if(using_utf_locale==false && found_bom==true)
Jakub Martisko 0a63fa
+                    {
Jakub Martisko 0a63fa
+                      /*First file conatined BOM header - locale was switched to UTF 
Jakub Martisko 0a63fa
+                      /*all subsequent files should contain BOM. */
Jakub Martisko 0a63fa
+                      error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
Jakub Martisko 0a63fa
+                    }
Jakub Martisko 0a63fa
+                  }
Jakub Martisko 0a63fa
+                }
Jakub Martisko 0a63fa
                 continue;
Jakub Martisko 0a63fa
               }
Jakub Martisko 0a63fa
             else
Kamil Dudka 8d9eac
diff --git a/src/unexpand.c b/src/unexpand.c
Kamil Dudka 8d9eac
index 863a90a..5681b58 100644
Kamil Dudka 8d9eac
--- a/src/unexpand.c
Kamil Dudka 8d9eac
+++ b/src/unexpand.c
Kamil Dudka 8d9eac
@@ -116,16 +116,36 @@ unexpand (void)
Jakub Martisko 0a63fa
      include characters other than spaces, so the blanks must be
Jakub Martisko 0a63fa
      stored, not merely counted.  */
Jakub Martisko 0a63fa
   mbf_char_t *pending_blank;
Jakub Martisko 0a63fa
+  /* True if the starting locale is utf8.  */
Jakub Martisko 0a63fa
+  bool using_utf_locale;
Jakub Martisko 0a63fa
+ 
Jakub Martisko 0a63fa
+  /* True if the first file contains BOM header.  */
Jakub Martisko 0a63fa
+  bool found_bom;
Jakub Martisko 0a63fa
+  using_utf_locale=check_utf_locale();
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
   if (!fp)
Jakub Martisko 0a63fa
     return;
Jakub Martisko 0a63fa
+  mbf_init (mbf, fp);
Jakub Martisko 0a63fa
+  found_bom=check_bom(fp,&mbf);
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
+  if (using_utf_locale == false && found_bom == true)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    /*try using some predefined locale */
Jakub Martisko 0a63fa
+    
Jakub Martisko 0a63fa
+    if (set_utf_locale () != 0)
Jakub Martisko 0a63fa
+    {
Jakub Martisko 0a63fa
+      error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
Jakub Martisko 0a63fa
+    }
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
   /* The worst case is a non-blank character, then one blank, then a
Jakub Martisko 0a63fa
      tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so
Jakub Martisko 0a63fa
      allocate MAX_COLUMN_WIDTH bytes to store the blanks.  */
Jakub Martisko 0a63fa
   pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t));
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
-  mbf_init (mbf, fp);
Jakub Martisko 0a63fa
+  if (found_bom == true)
Jakub Martisko 0a63fa
+  {
Jakub Martisko 0a63fa
+    print_bom();
Jakub Martisko 0a63fa
+  }
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
   while (true)
Jakub Martisko 0a63fa
     {
Kamil Dudka 8d9eac
@@ -169,6 +189,27 @@ unexpand (void)
Jakub Martisko 0a63fa
             if ((mb_iseof (c)) && (fp = next_file (fp)))
Jakub Martisko 0a63fa
               {
Jakub Martisko 0a63fa
                 mbf_init (mbf, fp);
Jakub Martisko 0a63fa
+                if (fp!=NULL)
Jakub Martisko 0a63fa
+                {
Jakub Martisko 0a63fa
+                  if (check_bom(fp,&mbf)==true)
Jakub Martisko 0a63fa
+                  {
Jakub Martisko 0a63fa
+                    /*Not the first file - check BOM header*/
Jakub Martisko 0a63fa
+                    if (using_utf_locale==false && found_bom==false)
Jakub Martisko 0a63fa
+                    {
Jakub Martisko 0a63fa
+                      /*BOM header in subsequent file but not in the first one. */
Jakub Martisko 0a63fa
+                      error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
Jakub Martisko 0a63fa
+                    }
Jakub Martisko 0a63fa
+                  }
Jakub Martisko 0a63fa
+                  else
Jakub Martisko 0a63fa
+                  {
Jakub Martisko 0a63fa
+                    if(using_utf_locale==false && found_bom==true)
Jakub Martisko 0a63fa
+                    {
Jakub Martisko 0a63fa
+                      /*First file conatined BOM header - locale was switched to UTF 
Jakub Martisko 0a63fa
+                      /*all subsequent files should contain BOM. */
Jakub Martisko 0a63fa
+                      error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
Jakub Martisko 0a63fa
+                    }
Jakub Martisko 0a63fa
+                  }
Jakub Martisko 0a63fa
+                }
Jakub Martisko 0a63fa
                 continue;
Jakub Martisko 0a63fa
               }
Jakub Martisko 0a63fa
             else
Kamil Dudka 8d9eac
diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh
Kamil Dudka 8d9eac
index 031be7a..1621c84 100755
Kamil Dudka 8d9eac
--- a/tests/expand/mb.sh
Kamil Dudka 8d9eac
+++ b/tests/expand/mb.sh
Kamil Dudka 8d9eac
@@ -109,4 +109,75 @@ env printf '12345678
Jakub Martisko 0a63fa
 expand < in > out || fail=1
Jakub Martisko 0a63fa
 compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+#BOM header test 1 
Jakub Martisko 0a63fa
+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a	b	c	d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä	ö	ü	ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+env printf '   äöü\t.    öüä.   \tä xx\n' >> in || framework_failure_
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a       b       c       d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä       ö       ü       ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+   äöü  .    öüä.       ä xx
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+expand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LANG=C expand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LC_ALL=C expand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a	b	c	d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä	ö	ü	ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+env printf '   äöü\t.    öüä.   \tä xx\n' >> in1 || framework_failure_
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a       b       c       d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä       ö       ü       ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+   äöü  .    öüä.       ä xx
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a       b       c       d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä       ö       ü       ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+   äöü  .    öüä.       ä xx
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+expand in1 in1 > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LANG=C expand in1 in1  > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LC_ALL=C expand in1 in1 > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
 exit $fail
Kamil Dudka 8d9eac
diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh
Kamil Dudka 8d9eac
index 8d75652..9d4ee3e 100755
Kamil Dudka 8d9eac
--- a/tests/unexpand/mb.sh
Kamil Dudka 8d9eac
+++ b/tests/unexpand/mb.sh
Kamil Dudka 8d9eac
@@ -111,3 +111,62 @@ env printf '12345678
Jakub Martisko 0a63fa
 
Jakub Martisko 0a63fa
 unexpand -a < in > out || fail=1
Jakub Martisko 0a63fa
 compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+#BOM header test 1 
Jakub Martisko 0a63fa
+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+a       b       c       d
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+ä       ö       ü       ß
Jakub Martisko 0a63fa
+.       .       .       .
Jakub Martisko 0a63fa
+   äöü  .    öüä.       ä xx
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+env printf '   äöü\t.    öüä.   \tä xx\n' >> in || framework_failure_
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+a	b	c	d
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+ä	ö	ü	ß
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+   äöü	.    öüä.	ä xx
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+unexpand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LANG=C unexpand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LC_ALL=C unexpand < in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+a	b	c	d
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+ä	ö	ü	ß
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+   äöü	.    öüä.	ä xx
Jakub Martisko 0a63fa
+1234567812345678123456781
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+a	b	c	d
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+ä	ö	ü	ß
Jakub Martisko 0a63fa
+.	.	.	.
Jakub Martisko 0a63fa
+   äöü	.    öüä.	ä xx
Jakub Martisko 0a63fa
+EOF
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+unexpand in in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LANG=C unexpand in in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1
Jakub Martisko 0a63fa
+
Jakub Martisko 0a63fa
+LC_ALL=C unexpand in in > out || fail=1
Jakub Martisko 0a63fa
+compare exp out > /dev/null 2>&1 || fail=1