From c7f543a57fc4feb9abb8ce97ff857db9f20026c7 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Fri, 17 May 2013 08:38:57 +0000 Subject: Update the docs. * NEWS: Update. * doc/gdbm.texinfo: Update. * doc/gdbmtool.1: Document the "define" statement. * src/datconv.c: Rename string datatypes to reflect their meaning. (dsprint): Improve output presentation. --- ChangeLog | 11 +++++++ NEWS | 25 ++++++++++++++-- doc/gdbm.texinfo | 51 +++++++++++++++++++-------------- doc/gdbmtool.1 | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/datconv.c | 33 ++++++++++++++------- 5 files changed, 170 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 087bd07..cb37efc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-05-17 Sergey Poznyakoff + + Update the docs. + + * NEWS: Update. + * doc/gdbm.texinfo: Update. + * doc/gdbmtool.1: Document the "define" statement. + * src/datconv.c: Rename string datatypes to reflect their + meaning. + (dsprint): Improve output presentation. + 2013-05-16 Sergey Poznyakoff Provide support for a simplified "define" construct. diff --git a/NEWS b/NEWS index a45b6b0..17bb8fe 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ -GNU dbm NEWS -- history of user-visible changes. 2011-11-15 -Copyright (C) 1990-2011 Free Software Foundation, Inc. +GNU dbm NEWS -- history of user-visible changes. 2013-05-17 +Copyright (C) 1990-2013 Free Software Foundation, Inc. See the end of file for copying conditions. Please send gdbm bug reports to . @@ -9,6 +9,25 @@ Version 1.10.90 (Git) * Improved dump format. * New utilities: gdbm_dump and gdbm_load. +Gdbm_dump create a plain-text dump of the GDBM database. This dump +can be used to create an exact copy of the database afterward. + +The gdbm_load performs the reverse: given the dump file, it creates a +GDBM database. Apart from the GDBM dump format, it also understands +the format generated by Berkeley DB db_dump utility. Thus, an easy +way to convert a Berkeley DB database to GDBM is: + + db_dump input.db | gdbm_load output.db + +* gdbmtool + +The gdbmtool utility allows you to examine, modify or create GDBM +databases. It provides an easy-to-use interactive shell and can +be used for scripting. One of the unique features of gdbmtool is that +it allows to define datum structures for key and content parts, similarly +to the C "struct" declarations, and to input and display such +structured data. + Version 1.10, 2011-11-13 @@ -199,7 +218,7 @@ Version 0.9 ---------------------------------------------------------------------- Copyright information: -Copyright (C) 1990-2011 Free Software Foundation, Inc. +Copyright (C) 1990-2013 Free Software Foundation, Inc. Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the diff --git a/doc/gdbm.texinfo b/doc/gdbm.texinfo index 00acc41..0d58f64 100644 --- a/doc/gdbm.texinfo +++ b/doc/gdbm.texinfo @@ -773,7 +773,7 @@ this error equally as @samp{GDBM_ILLEGAL_DATA}. Mild errors mean that the function was able to successfully load and restore the data, but was unable to change database file metadata -afterwards. The table below lists possible values for @code{gdbm_errno} +afterward. The table below lists possible values for @code{gdbm_errno} in this case. To get more detail, inspect the system @code{errno} variable. @table @asis @@ -2078,7 +2078,7 @@ for a list of its values. @item lock Whether or not to lock the database. Default is @samp{on}. @item mmap -Use the memmory mapping. Default is @samp{on}. +Use the memory mapping. Default is @samp{on}. @item sync Synchronize after each write. Default is @samp{off}. @end table @@ -2105,13 +2105,13 @@ information displayed: @example Database file: junk.gdbm Database is open -define key @{ - string, -@} -define content @{ - string, -@} +define key string +define content string @end example + +The two @samp{define} strings show the defined formats for key and +content data. @xref{definitions}, for a detailed discussion of their +meaning. @end deffn @deffn {command verb} store @var{key} @var{data} @@ -2174,37 +2174,39 @@ Signed long long integer. @item ullong Unsigned long long integer. @item float -A float. +A floating point number. @item double -A double. +Double-precision floating point number. @item string +Array of bytes. +@item stringz Null-terminated string, trailing null being part of the string. -@item zstring -A string of characters without the terminating null. @end table All numeric data types (integer as well as floating point) have the same respective widths as in C language on the host where the database file resides. -The @samp{string} and @samp{zstring} are special. Both define a +The @samp{string} and @samp{stringz} are special. Both define a string of bytes, similar to @samp{char x[]} in C. The former -defines a null-terminated string, the latter - a string without null -terminator. This makes difference when the string is the only part of -datum. Consider the following two definitions: +defines an array of bytes, the latter - a null-terminated string. +This makes a difference, in particular, when the string is the only +part of datum. Consider the following two definitions: @enumerate 1 @item @code{define key string} -@item @code{define key zstring} +@item @code{define key stringz} @end enumerate @noindent Now, suppose we want to store the string "ab" in the key. Using the definition (1), the @code{dptr} member of GDBM @code{datum} will -contain three bytes: @samp{a}, @samp{b}, and ASCII 0. The -@code{dsize} member will have the value 3. Using the definition (2), -the @code{dptr} member will contain two bytes: @samp{a} and @samp{b}, -and the @code{dsize} member will have the value 2. +contain two bytes: @samp{a}, and @samp{b}. Consequently, the +@code{dsize} member will have the value 2. Using the definition (2), +the @code{dptr} member will contain three bytes: @samp{a}, @samp{b}, +and ASCII 0. The @code{dsize} member will have the value 3. + +The definition (1) is the default for both key and content. The second form of the @code{define} statement is similar to the C @code{struct} statement and allows for defining structural data. In @@ -2241,6 +2243,11 @@ define content @{ @} @end example +@empth{NOTE}: The @samp{string} type can reasonably be used only if it +is the last or the only member of the data structure. That's because it +provides no information about the number of elements in the array, so +it is interpreted to contain all bytes up to the end of the datum. + When displaying the structured data, @command{gdbmtool} precedes each value with the corresponding field name and delimits parts of the structure with the string defined in the @samp{delim1} variable @@ -2282,7 +2289,7 @@ records: @group set quiet set ps1="(%f) " - +define key stringz define content @{ int time, pad 4, diff --git a/doc/gdbmtool.1 b/doc/gdbmtool.1 index 2326a32..a04fbef 100644 --- a/doc/gdbmtool.1 +++ b/doc/gdbmtool.1 @@ -13,7 +13,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with GDBM. If not, see . */ -.TH GDBM_DUMP 1 "May 9, 2013" "GDBM" "GDBM User Reference" +.TH GDBM_DUMP 1 "May 17, 2013" "GDBM" "GDBM User Reference" .SH NAME gdbmtool \- examine and modify a GDBM database .SH SYNOPSIS @@ -244,6 +244,91 @@ Unsets listed variables. Print the version of .BR gdbm . .SH "DATA DEFINITIONS" +The \fBdefine\fR statement provides a mechanism for defining key or +content structures. It is similar to the \fBC\fR \fBstruct\fR +declaration: +.sp +.nf +.in +4 +\fBdefine\fR \fBkey\fR|\fBcontent\fR \fB{\fR \fIdefnlist\fR \fB}\fR +.in +.fi +.PP +The \fIdefnlist\fR is a comma-separated list of member declarations. +Within \fIdefnlist\fR the newline character looses its special meaning +as the command terminator, so each declaration can appear on a +separate line and arbitrary number of comments can be inserted to +document the definition. +.PP +Each declaration has one of the following formats +.sp +.nf +.in +4 +\fItype\fR \fIname\fR +\fItype\fR \fIname\fR \fB[\fIN\fB]\fR +.in +.fi +.sp +where \fItype\fR is a data type and \fIname\fR is the member name. +The second format defines the member \fIname\fR as an array of \fIN\fR +elements of \fItype\fR. +.PP +The supported types are: +.sp +.nf +.ta 8n 20n +.ul + type meaning + char single byte (signed) + short signed short integer + ushort unsigned short integer + int signed integer + unsigned unsigned integer + uint ditto + long signed long integer + ulong unsigned long integer + llong signed long long integer + ullong unsigned long long integer + float a floating point number + double double-precision floating point number + string array of characters (see the \fBNOTE\fR below) + stringz null-terminated string of characters +.fi +.PP +The following alignment declarations can be used within \fIdefnlist\fR: +.TP +\fBoffset\fR \fIN\fR +The next member begins at offset \fIN\fR. +.TP +\fBpad\fR \fIN\fR +Add \fIN\fR bytes of padding to the previous member. +.PP +For example: +.sp +.nf +.in +4 +\fBdefine content { + int status, + pad 8, + char id[3], + stringz name +}\fR +.fi +.PP +To define data consisting of a single data member, the following +simplified construct can be used: +.sp +.nf +.in +4 +\fBdefine\fR \fBkey\fR|\fBcontent\fR \fItype\fR +.fi +.PP +where \fItype\fR is one of the types discussed above. +.PP +\fBNOTE\fR: The \fBstring\fR type can reasonably be used only if it is +the last or the only member of the data structure. That's because it +provides no information about the number of elements in the array, so +it is interpreted to contain all bytes up to the end of the datum. .SH VARIABLES .TP .BR confirm ", boolean" diff --git a/src/datconv.c b/src/datconv.c index c8f63e0..c4adfa4 100644 --- a/src/datconv.c +++ b/src/datconv.c @@ -38,7 +38,7 @@ DEFFMT (f_float, float, "%f") DEFFMT (f_double, double, "%e") static int -f_string (FILE *fp, void *ptr, int size) +f_stringz (FILE *fp, void *ptr, int size) { int sz; char *s; @@ -58,7 +58,7 @@ f_string (FILE *fp, void *ptr, int size) } static int -f_zstring (FILE *fp, void *ptr, int size) +f_string (FILE *fp, void *ptr, int size) { int sz; char *s; @@ -140,14 +140,14 @@ s_float (struct xdatum *xd, char *str) } int -s_string (struct xdatum *xd, char *str) +s_stringz (struct xdatum *xd, char *str) { xd_store (xd, str, strlen (str) + 1); return 0; } int -s_zstring (struct xdatum *xd, char *str) +s_string (struct xdatum *xd, char *str) { xd_store (xd, str, strlen (str)); return 0; @@ -166,8 +166,8 @@ static struct datadef datatab[] = { { "ullong", sizeof(unsigned long long), f_ullong, s_ullong }, { "float", sizeof(float), f_float, s_float }, { "double", sizeof(double), f_double, s_double }, + { "stringz", 0, f_stringz, s_stringz }, { "string", 0, f_string, s_string }, - { "zstring", 0, f_zstring, s_zstring }, { NULL } }; @@ -403,29 +403,40 @@ void dsprint (FILE *fp, int what, struct dsegm *ds) { static char *dsstr[] = { "key", "content" }; + int delim; - fprintf (fp, "define %s {\n", dsstr[what]); + fprintf (fp, "define %s", dsstr[what]); + if (ds->next) + { + fprintf (fp, " {\n"); + delim = '\t'; + } + else + delim = ' '; for (; ds; ds = ds->next) { switch (ds->type) { case FDEF_FLD: - fprintf (fp, "\t%s", ds->v.field.type->name); + fprintf (fp, "%c%s", delim, ds->v.field.type->name); if (ds->v.field.name) fprintf (fp, " %s", ds->v.field.name); if (ds->v.field.dim > 1) fprintf (fp, "[%d]", ds->v.field.dim); - fprintf (fp, ",\n"); break; case FDEF_OFF: - fprintf (fp, "\toffset %d,\n", ds->v.n); + fprintf (fp, "%coffset %d", delim, ds->v.n); break; case FDEF_PAD: - fprintf (fp, "\tpad %d,\n", ds->v.n); + fprintf (fp, "%cpad %d", delim, ds->v.n); break; } + if (ds->next) + fputc (',', fp); + fputc ('\n', fp); } - fprintf (fp, "}\n"); + if (delim == '\t') + fputs ("}\n", fp); } -- cgit v1.2.1