work on print encodigns
[pspp] / src / language / data-io / print.c
index 7b795f1ade5c8365e5a4bf68e7cd039c6a9a14c6..71791ba59541573b8b2f192f2627ea4182962bca 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    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
@@ -88,7 +88,11 @@ struct print_trns
     struct dfm_writer *writer; /* Output file, NULL=listing file. */
     struct ll_list specs;       /* List of struct prt_out_specs. */
     size_t record_cnt;          /* Number of records to write. */
-    struct string line;         /* Output buffer. */
+    struct u8_line line;        /* Output buffer. */
+
+    int unit;                   /* Unit width, in bytes. */
+    char one[MAX_UNIT];         /* '1' in encoding, 'unit' bytes long. */
+    char space[MAX_UNIT];       /* \n in encoding, 'unit' bytes long. */
   };
 
 enum which_formats
@@ -136,6 +140,7 @@ internal_cmd_print (struct lexer *lexer, struct dataset *ds,
   bool print_table = 0;
   struct print_trns *trns;
   struct file_handle *fh = NULL;
+  char *encoding = NULL;
   struct pool *tmp_pool;
 
   /* Fill in prt to facilitate error-handling. */
@@ -144,8 +149,8 @@ internal_cmd_print (struct lexer *lexer, struct dataset *ds,
   trns->writer = NULL;
   trns->record_cnt = 0;
   ll_init (&trns->specs);
-  ds_init_empty (&trns->line);
-  ds_register_pool (&trns->line, trns->pool);
+  u8_line_init (&trns->line);
+  u8_line_register_pool (&trns->line, trns->pool);
 
   tmp_pool = pool_create_subpool (trns->pool);
 
@@ -160,6 +165,17 @@ internal_cmd_print (struct lexer *lexer, struct dataset *ds,
          if (fh == NULL)
            goto error;
        }
+      else if (lex_match_id (lexer, "ENCODING"))
+       {
+         lex_match (lexer, T_EQUALS);
+         if (!lex_force_string (lexer))
+           goto error;
+
+          free (encoding);
+          encoding = ss_xstrdup (lex_tokss (lexer));
+
+         lex_get (lexer);
+       }
       else if (lex_match_id (lexer, "RECORDS"))
        {
          lex_match (lexer, T_EQUALS);
@@ -194,10 +210,10 @@ internal_cmd_print (struct lexer *lexer, struct dataset *ds,
 
   if (fh != NULL)
     {
-      trns->writer = dfm_open_writer (fh);
+      trns->writer = dfm_open_writer (fh, encoding);
       if (trns->writer == NULL)
         goto error;
-      trns->encoding = dfm_writer_get_legacy_encoding (trns->writer);
+      trns->encoding = dfm_writer_get_encoding (trns->writer);
     }
   else
     trns->encoding = UTF8;
@@ -325,7 +341,7 @@ parse_variable_argument (struct lexer *lexer, const struct dictionary *dict,
 
   if (lex_is_number (lexer) || lex_token (lexer) == T_LPAREN)
     {
-      if (!parse_var_placements (lexer, tmp_pool, var_cnt, false,
+      if (!parse_var_placements (lexer, tmp_pool, var_cnt, FMT_FOR_OUTPUT,
                                  &formats, &format_cnt))
         return false;
       add_space = false;
@@ -458,20 +474,33 @@ print_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED)
   int record = 1;
   struct prt_out_spec *spec;
 
-  ds_clear (&trns->line);
-  ds_put_byte (&trns->line, ' ');
+  u8_line_clear (&trns->line);
+
+  ds_put_byte (&trns->line.s, ' ');
+  trns->line.width = 0;
+
   ll_for_each (spec, struct prt_out_spec, ll, &trns->specs)
     {
       flush_records (trns, spec->record, &eject, &record);
 
-      ds_set_length (&trns->line, spec->first_column, encoded_space);
       if (spec->type == PRT_VAR)
         {
           const union value *input = case_data (*c, spec->var);
           if (!spec->sysmis_as_spaces || input->f != SYSMIS)
-            data_out_recode (input, var_get_encoding (spec->var),
-                             &spec->format, &trns->line, trns->encoding);
+            {
+              char *s = data_out (input, var_get_encoding (spec->var),
+                                  &spec->format);
+              int width = u8_strwidth (s);
+              size_t n = strlen (s);
+              u8_line_put (&trns->line, spec->first_column,
+                           spec->first_column + width, s, n);
+              free (s);
+            }
           else
+            {
+              memset (u8_line-record
+
+            }
             ds_put_byte_multiple (&trns->line, encoded_space, spec->format.w);
           if (spec->add_space)
             ds_put_byte (&trns->line, encoded_space);
@@ -479,11 +508,11 @@ print_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED)
       else
         {
           ds_put_substring (&trns->line, ds_ss (&spec->string));
-          if (0 != strcmp (trns->encoding, C_ENCODING))
+          if (0 != strcmp (trns->encoding, UTF8))
             {
               size_t length = ds_length (&spec->string);
               char *data = ss_data (ds_tail (&trns->line, length));
-             char *s = recode_string (trns->encoding, C_ENCODING, data, length);
+             char *s = recode_string (trns->encoding, UTF8, data, length);
              memcpy (data, s, length);
              free (s);
             }