Implemented ADD DOCUMENT. Thanks to Ben Pfaff for review.
authorJohn Darrington <john@darrington.wattle.id.au>
Thu, 3 May 2007 10:15:26 +0000 (10:15 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Thu, 3 May 2007 10:15:26 +0000 (10:15 +0000)
doc/utilities.texi
po/de.po
po/pspp.pot
src/data/sys-file-writer.c
src/language/command.def
src/language/lexer/ChangeLog
src/language/lexer/lexer.c
src/language/lexer/lexer.h
src/language/utilities/ChangeLog
src/language/utilities/title.c
tests/command/file-label.sh

index 3196684966eadb474eafe4ca6e0c87baa73ec656..009706e22584dc8591508992813cd6d4ff08cd9d 100644 (file)
@@ -9,6 +9,7 @@ they take effect only once, unconditionally, at the time that they are
 encountered in the input.
 
 @menu
+* ADD DOCUMENT::                Add documentary text to the active file.
 * COMMENT::                     Document your syntax file.
 * DOCUMENT::                    Document the active file.
 * DISPLAY DOCUMENTS::           Display active file documents.
@@ -28,7 +29,29 @@ encountered in the input.
 * TITLE::                       Provide a document title.
 @end menu
 
-@node COMMENT, DOCUMENT, Utilities, Utilities
+@node ADD DOCUMENT, COMMENT, Utilities, Utilities
+@comment  node-name,  next,  previous,  up
+@section ADD DOCUMENT
+@vindex  ADD DOCUMENT
+
+@display
+ADD DOCUMENT 
+    'line one' 'line two' @dots{} 'last line' .
+@end display
+
+
+@cmd{ADD DOCUMENT} adds one or more lines of descriptive commentary to 
+the active file.  Documents added in this way are saved to system files.
+They can be viewed using @cmd{SYSFILE INFO} or @cmd{DISPLAY
+DOCUMENTS}.  They can be removed from the active file with @cmd{DROP
+DOCUMENTS}.
+
+Each line of documentary text must be enclosed in quotation marks, and 
+may not be more than 80 bytes long. @xref{DOCUMENT}.
+
+
+
+@node COMMENT, DOCUMENT, ADD DOCUMENT, Utilities
 @section COMMENT
 @vindex COMMENT
 @vindex *
@@ -45,12 +68,14 @@ the author and other readers of the PSPP syntax file.
 @cmd{COMMENT} can extend over any number of lines.  Don't forget to
 terminate it with a dot or a blank line.
 
+
+
 @node DOCUMENT, DISPLAY DOCUMENTS, COMMENT, Utilities
 @section DOCUMENT
 @vindex DOCUMENT
 
 @display
-DOCUMENT documentary_text.
+DOCUMENT @var{documentary_text}.
 @end display
 
 @cmd{DOCUMENT} adds one or more lines of descriptive commentary to the
@@ -59,10 +84,12 @@ They can be viewed using @cmd{SYSFILE INFO} or @cmd{DISPLAY
 DOCUMENTS}.  They can be removed from the active file with @cmd{DROP
 DOCUMENTS}.
 
-Specify the documentary text following the DOCUMENT keyword.  You can
-extend the documentary text over as many lines as necessary.  Lines are
-truncated at 80 characters width.  Don't forget to terminate
-the command with a dot or a blank line.
+Specify the @var{documentary text} following the DOCUMENT keyword.  
+It is interpreted literally --- any quotes or other punctuation marks 
+will be included in the file.
+You can extend the documentary text over as many lines as necessary.  
+Lines are truncated at 80 bytes.  Don't forget to terminate
+the command with a dot or a blank line. @xref{ADD DOCUMENT}.
 
 @node DISPLAY DOCUMENTS, DISPLAY FILE LABEL, DOCUMENT, Utilities
 @section DISPLAY DOCUMENTS
index 8c48fdb6a84e85426b8156e73ddbf3db48869b7e..5ce521accd14d716e3915367ed5f6843cc1cc9b3 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PSPP 0.4.2\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2007-04-29 12:09+0800\n"
+"POT-Creation-Date: 2007-05-02 14:35+0800\n"
 "PO-Revision-Date: 2006-05-26 17:49+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: German <pspp-dev@gnu.org>\n"
@@ -795,7 +795,7 @@ msgstr ""
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-writer.c:1104
+#: src/data/sys-file-writer.c:1101
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
@@ -1763,11 +1763,11 @@ msgid ""
 "s."
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:158 src/language/lexer/lexer.c:600
+#: src/language/dictionary/value-labels.c:158 src/language/lexer/lexer.c:609
 msgid "expecting string"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:167 src/language/lexer/lexer.c:614
+#: src/language/dictionary/value-labels.c:167 src/language/lexer/lexer.c:623
 msgid "expecting integer"
 msgstr ""
 
@@ -2044,54 +2044,54 @@ msgstr ""
 msgid "Syntax error at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:569 src/language/lexer/lexer.c:586
+#: src/language/lexer/lexer.c:578 src/language/lexer/lexer.c:595
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
-#: src/language/lexer/lexer.c:627
+#: src/language/lexer/lexer.c:636
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:639
+#: src/language/lexer/lexer.c:648
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1028
+#: src/language/lexer/lexer.c:1037
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1033
+#: src/language/lexer/lexer.c:1042
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1038
+#: src/language/lexer/lexer.c:1047
 msgid "hex"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1048
+#: src/language/lexer/lexer.c:1057
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1077
+#: src/language/lexer/lexer.c:1086
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1111
+#: src/language/lexer/lexer.c:1120
 msgid "Unterminated string constant."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1165
+#: src/language/lexer/lexer.c:1174
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1173
+#: src/language/lexer/lexer.c:1182
 msgid "String expected following `+'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1186
+#: src/language/lexer/lexer.c:1195
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
@@ -3415,6 +3415,24 @@ msgstr ""
 msgid "Closing `%s': %s."
 msgstr ""
 
+#: src/language/tests/check-model.q:139
+msgid "PATH and SEARCH subcommands are mutually exclusive.  Ignoring PATH."
+msgstr ""
+
+#: src/language/tests/check-model.q:157
+msgid "At least one value must be specified on PATH."
+msgstr ""
+
+#: src/language/tests/check-model.q:168
+#, c-format
+msgid "Hash bits adjusted to %d."
+msgstr ""
+
+#: src/language/tests/check-model.q:209
+#, c-format
+msgid "error opening \"%s\" for writing"
+msgstr ""
+
 #: src/language/tests/float-format.c:126
 #, c-format
 msgid "%d-byte string needed but %d-byte string supplied."
@@ -3614,6 +3632,15 @@ msgstr ""
 msgid "Document entered %s by %s:"
 msgstr ""
 
+#: src/language/utilities/title.c:184
+#, c-format
+msgid "(Entered %s)"
+msgstr ""
+
+#: src/language/utilities/title.c:195
+msgid "Document lines may not be more than 80 bytes long"
+msgstr ""
+
 #: src/language/xforms/compute.c:147 src/language/xforms/compute.c:195
 #, c-format
 msgid ""
index 42bfa2afd8406efceddb4bf03ba15e681fd03b84..754e5c57af414c85c37adcc1103e37f36022a722 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2007-04-29 12:09+0800\n"
+"POT-Creation-Date: 2007-05-02 14:35+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -790,7 +790,7 @@ msgstr ""
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-writer.c:1104
+#: src/data/sys-file-writer.c:1101
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
@@ -1758,11 +1758,11 @@ msgid ""
 "s."
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:158 src/language/lexer/lexer.c:600
+#: src/language/dictionary/value-labels.c:158 src/language/lexer/lexer.c:609
 msgid "expecting string"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:167 src/language/lexer/lexer.c:614
+#: src/language/dictionary/value-labels.c:167 src/language/lexer/lexer.c:623
 msgid "expecting integer"
 msgstr ""
 
@@ -2039,54 +2039,54 @@ msgstr ""
 msgid "Syntax error at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:569 src/language/lexer/lexer.c:586
+#: src/language/lexer/lexer.c:578 src/language/lexer/lexer.c:595
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
-#: src/language/lexer/lexer.c:627
+#: src/language/lexer/lexer.c:636
 msgid "expecting number"
 msgstr ""
 
-#: src/language/lexer/lexer.c:639
+#: src/language/lexer/lexer.c:648
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1028
+#: src/language/lexer/lexer.c:1037
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1033
+#: src/language/lexer/lexer.c:1042
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1038
+#: src/language/lexer/lexer.c:1047
 msgid "hex"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1048
+#: src/language/lexer/lexer.c:1057
 #, c-format
 msgid "String of %s digits has %d characters, which is not a multiple of %d."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1077
+#: src/language/lexer/lexer.c:1086
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1111
+#: src/language/lexer/lexer.c:1120
 msgid "Unterminated string constant."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1165
+#: src/language/lexer/lexer.c:1174
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1173
+#: src/language/lexer/lexer.c:1182
 msgid "String expected following `+'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1186
+#: src/language/lexer/lexer.c:1195
 #, c-format
 msgid "String exceeds 255 characters in length (%d characters)."
 msgstr ""
@@ -3409,6 +3409,24 @@ msgstr ""
 msgid "Closing `%s': %s."
 msgstr ""
 
+#: src/language/tests/check-model.q:139
+msgid "PATH and SEARCH subcommands are mutually exclusive.  Ignoring PATH."
+msgstr ""
+
+#: src/language/tests/check-model.q:157
+msgid "At least one value must be specified on PATH."
+msgstr ""
+
+#: src/language/tests/check-model.q:168
+#, c-format
+msgid "Hash bits adjusted to %d."
+msgstr ""
+
+#: src/language/tests/check-model.q:209
+#, c-format
+msgid "error opening \"%s\" for writing"
+msgstr ""
+
 #: src/language/tests/float-format.c:126
 #, c-format
 msgid "%d-byte string needed but %d-byte string supplied."
@@ -3608,6 +3626,15 @@ msgstr ""
 msgid "Document entered %s by %s:"
 msgstr ""
 
+#: src/language/utilities/title.c:184
+#, c-format
+msgid "(Entered %s)"
+msgstr ""
+
+#: src/language/utilities/title.c:195
+msgid "Document lines may not be more than 80 bytes long"
+msgstr ""
+
 #: src/language/xforms/compute.c:147 src/language/xforms/compute.c:195
 #, c-format
 msgid ""
index 34f59d332d1544abf2bdd67497d228ab6f88ee45..13916d8bdfb5a36cdb9534cb49562faf4b651a91 100644 (file)
@@ -662,16 +662,15 @@ write_documents (struct sfm_writer *w, const struct dictionary *d)
     int32_t n_lines ;          /* Number of lines of documents. */
   } ATTRIBUTE((packed)) rec_6;
 
-  const char *documents;
-  size_t n_lines;
+  const char * documents = dict_get_documents (d);
+  size_t doc_bytes = strlen (documents);
 
-  documents = dict_get_documents (d);
-  n_lines = strlen (documents) / 80;
+  assert (doc_bytes % 80 == 0);
 
   rec_6.rec_type = 6;
-  rec_6.n_lines = n_lines;
+  rec_6.n_lines = doc_bytes / 80;
   buf_write (w, &rec_6, sizeof rec_6);
-  buf_write (w, documents, 80 * n_lines);
+  buf_write (w, documents, 80 * rec_6.n_lines);
 }
 
 /* Write the alignment, width and scale values */
index a8d835ed4987dd0e03e564d362914a4e5e8efd54..4abf839bda2fd1d554ab383dc61f8919272f1a21 100644 (file)
@@ -48,6 +48,7 @@ DEF_CMD (S_INITIAL | S_DATA, 0, "INPUT PROGRAM", cmd_input_program)
 /* Transformations and utilities that may appear after active
    file definition or within INPUT PROGRAM. */
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "ADD VALUE LABELS", cmd_add_value_labels)
+DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "ADD DOCUMENT", cmd_add_documents)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "APPLY DICTIONARY", cmd_apply_dictionary)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "BREAK", cmd_break)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "COMPUTE", cmd_compute)
index a3fb55bf8092597f39321e6604b291965f7f29a3..c10e681b4ca628d71bbf62a8a246416a9c88c259 100644 (file)
@@ -1,3 +1,7 @@
+2007-05-03  John Darrington <john@darrington.wattle.id.au>
+       
+       * lexer.c lexer.h: Added lex_is_string function.
+       
 2007-04-15  Ben Pfaff  <blp@gnu.org>
 
        * q2c.c: Fully support lists of integer values.  Add support for
index 68dd1c8638f190aea05bedd096912f3b07e34c11..6396ecea5f4ea27414898f9320bcd734795129d6 100644 (file)
@@ -478,6 +478,15 @@ lex_is_number (struct lexer *lexer)
   return lexer->token == T_POS_NUM || lexer->token == T_NEG_NUM;
 }
 
+
+/* Returns true if the current token is a string. */
+bool
+lex_is_string (struct lexer *lexer)
+{
+  return lexer->token == T_STRING;
+}
+
+
 /* Returns the value of the current token, which must be a
    floating point number. */
 double
index 4f9259250dadbd3fe5985afeef259ff584b64df6..47fbdd71602b201a38910678d94b529162fff430 100644 (file)
@@ -47,6 +47,8 @@ bool lex_is_number (struct lexer *);
 double lex_number (struct lexer *);
 bool lex_is_integer (struct lexer *);
 long lex_integer (struct lexer *);
+bool lex_is_string (struct lexer *);
+
 
 /* Token matching functions. */
 bool lex_match (struct lexer *, int);
index 6e98f435bd1d46ac4f33902c906229f0ef4c9cbf..de2d9ddad4ad1d3131d165c4bc9fb5b5e8088939 100644 (file)
@@ -1,3 +1,7 @@
+2007-05-03 John Darrington <john@darrington.wattle.ud.au>
+
+       * title.c: Implemented ADD DOCUMENT command.
+
 Sun Nov 19 09:21:39 2006  Ben Pfaff  <blp@gnu.org>
 
        * set.q: Add RIB, RRB settings to control binary formats used by
index 62c86530fe362e450b70a677e4198bd7392f0465..e7a463d10fde1b03690d4627486aae53a5fcd938 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007 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
@@ -174,3 +174,55 @@ cmd_drop_documents (struct lexer *lexer, struct dataset *ds)
 
   return lex_end_of_command (lexer);
 }
+
+
+/* Performs the ADD DOCUMENTS command. */
+int
+cmd_add_documents (struct lexer *lexer, struct dataset *ds)
+{
+  int i;
+  int n_lines = 0;
+  char buf[256];
+  struct string *lines = NULL;
+
+  sprintf (buf, _("(Entered %s)"), get_start_date ());
+
+  if ( ! lex_force_string (lexer) )
+    return CMD_FAILURE;
+
+  while ( lex_is_string (lexer))
+    {
+      const struct string *s = lex_tokstr (lexer);
+      if ( ds_length (s) > 80)
+       {
+         /* Note to translators: "bytes" is correct, not characters */
+         msg (SE, _("Document lines may not be more than 80 bytes long."));
+         goto failure;
+
+       }
+      lines = xrealloc (lines, (n_lines + 1) * sizeof (*lines));
+      ds_init_string (&lines[n_lines++], s);
+
+      lex_get (lexer);
+    }
+
+  for ( i = 0 ; i < n_lines ; ++i)
+    {
+      add_document_line (dataset_dict (ds), ds_cstr (&lines[i]), 0);
+      ds_destroy (&lines[i]);
+    }
+
+  free (lines);
+
+  add_document_line (dataset_dict (ds), buf, 3);
+
+  return lex_end_of_command (lexer) ;
+
+ failure:
+  for ( i = 0 ; i < n_lines ; ++i)
+    ds_destroy (&lines[i]);
+
+  free (lines);
+
+  return CMD_FAILURE;
+}
index 0d3500eb8dd4d6a67ee4f495705a8396c4fcd710..70a071502c139341855eb07c3933728324700673 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# This program tests the FILE LABEL and  DOCUMENT commands
+# This program tests the FILE LABEL and  DOCUMENT, and ADD DOCUMENT commands
 
 TEMPDIR=/tmp/pspp-tst-$$
 TESTFILE=$TEMPDIR/`basename $0`.sps
@@ -77,10 +77,13 @@ document First line of a document
 This is the second very long line of a document in an attempt to overflow the input buffer with a really long line
 Note that the last line should end with a period: .
 
+
 /* Display the documents.
 display documents.
 display file label.
 
+ADD DOCUMENT 'Line one' 'Line two'.
+
 /* Save the active file then get it and display the documents again.
 save /OUTFILE='foo.save'.
 get /FILE='foo.save'.
@@ -117,7 +120,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 
 # We need to filter out the dates/times
 activity="date filter"
-grep -v 'Document entered' $TEMPDIR/pspp.list > $TEMPDIR/pspp.filtered
+grep -v '[Ee]ntered' $TEMPDIR/pspp.list > $TEMPDIR/pspp.filtered
 if [ $? -ne 0 ] ; then no_result ; fi
 
 
@@ -141,17 +144,23 @@ Documents in the active file:
    First line of a document
    This is the second very long line of a document in an attempt to overflow the
    Note that the last line should end with a period: .
+Line one
+Line two
 File label:
 This is a test file label
 Documents in the active file:
    First line of a document
    This is the second very long line of a document in an attempt to overflow the
    Note that the last line should end with a period: .
+Line one
+Line two
    There should be another document now.
 Documents in the active file:
    First line of a document
    This is the second very long line of a document in an attempt to overflow the
    Note that the last line should end with a period: .
+Line one
+Line two
    There should be another document now.
 File label:
 This is a test file label