diff options
113 files changed, 12373 insertions, 0 deletions
@@ -0,0 +1,7 @@ +Main author of vformat + +Nick <Tilda@indigo8.freeserve.co.uk> + +Porting to Linux + +Mathias Palm <Mathias.Palm@gmx.net>
\ No newline at end of file @@ -0,0 +1,503 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Main author of vformat + +Nick <Tilda@indigo8.freeserve.co.uk> + +Porting to Linux + +Mathias Palm <Mathias.Palm@gmx.net> + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4fe7df9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,5 @@ +2002-11-22 Mathias Palm <mathias.palm@gmx.net> + + * manpages are generated from the header file and installed + +see README
\ No newline at end of file @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9ea4543 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src vformat test doc + +EXTRA_DIST = common/types.h vf_iface.h + @@ -0,0 +1,20 @@ +Posted By: tilda +Date: 2001-12-16 10:19 +Summary:Alpha 5 + +Alpha-5 is here! + +This is mostly a bugfix release over Alpha-4, new functionality will go into Alpha-6, which may be the last Alpha. + +Please note that from Alpha-5 onwards you will need DevIL from SourceForge. + + +Cheers, + +Nick + +Posted By: tilda +Date: 2001-10-24 13:47 +Summary:Alpha-2 + +Well; Alpha-2 is here - this is about as exciting as it gets isn't it...
\ No newline at end of file @@ -0,0 +1,207 @@ +/----------------------------------------------------------------------------- +| $Log: README,v $ +| Revision 1.1 2002/10/11 14:08:59 monos +| *** empty log message *** +| +| Revision 1.13 2001/12/28 17:29:29 tilda +| Minor tidy ups after updating to DevIL-1.2.4 +| +| Revision 1.12 2001/12/16 16:01:15 tilda +| Update release notes before Alpha-5 +| +| Revision 1.11 2001/12/10 09:28:35 tilda +| Typo. +| +| Revision 1.10 2001/12/10 09:21:47 tilda +| Describe image librrary build options. +| +| Revision 1.9 2001/12/02 21:20:25 tilda +| Update prior to Alpha-4 +| +| Revision 1.8 2001/11/27 18:32:59 tilda +| Reword LICENCING section in README.txt. Move docs into vformatl.dsp +| +\----------------------------------------------------------------------------- + +Welcome to the vFormat Library! + +LICENCE +======= + +All this software (the library and the demo apps) is distributed under the +GNU Lesser General Public Licence. A copy of this is distributed with the +library - see the file LICENCE.txt in the libraries root directory. + +Please read and understand the comments at the top of vf_iface.h before use. + + +RELEASES +======== +This will be considered "alpha" until all the features I think should be +there are there. It'll be "beta" until I know of no outstanding issues. +Release history: + +Alpha-1 : first cut at a release, known problems with BASE64, no create/modify API + +Alpha-2 : BASE64 encoding fixed, first pass at create/modify functionality + +Alpha-3 : including first usable version of vfedit demo app + +Alpha-4 : Add basic framework support for vCalendar to VFEDIT. Sort out tools menu + and font manager. Fix IIDs 485069, 485071, 488003, 484956, 488006, 488011. + Sort out various bugs in IMGHLP DLLs. + +Alpha-5 : Various bug fixes and move to use of a image library (DevIL from SourceForge) + rather than various dodgy home-grown bits'n'pieces. Fix IIDs 484685, 491475 + 489753, 484684, 488021, 484958, 484844, 484843. vfedit now reasonably usable + (for VCARDs). + + +BUILDING +======== + +Under Windows, the build uses Microsoft's Visual C++ version 6.0 - the +project & workspace files are included in the distribution. The workspace +at .../build/vformat/vformat.dsw references will build and install the +library (ie. the .DLL) and builds the test harness. In detail: + + .../build/vformat/vformat.dsw - workspace including other project files + .../build/vformatl/vformatl.dsp - builds (and installs) DLL version + .../build/tools - various tools & utilities + + .../build/vfdisplay - minimal app enumerating contents of a vobject + .../build/vfedit - demo app supporting VCARDs & VCALENDARs. + +Beware - vformatl.dsp and the other DSPs will install the DLLs in your +windows/system directory using the INSDLL.BAT file in the tools directory +which is invoked as a post-build step (see the post-build tab on the +projects/settings dialog). If you don't like this, delete the post +build step or edit the script to put the DLL somewhere else. + + + +IMAGE LIBRARY +============= +Imaging formats (.JPG etc) are handled in the demo applications using a 3rd party +open source image library. Early releases of VFEDIT used various bits of garbage +I'd collected over the years wrapped up in an .DLL (deliberately hiding the crap). + +As of Alpha-5, VFEDIT includes support for DevIL - the Developer's Image Libray. +Details of this can be found at http://OpenIL.sourceforge.net. + +To enable image support you need to download & install DevIL and change the line +at the top of ImageManager.cpp to #define USE_IMAGE_LIBRARY (rather than #undef). + +Here are the instructions to get a basic version of this going, this is based on +the install instructions included in DevIL & various things about my machine. The +basic version supports .BMP files, I've not (yet) got round to adding .JPG etc to +my build of DevIL. + + - download DevIL-1.2.4.zip from the page in SourceForge. + - unpack the .ZIP file somewhere convenient eg. D:\DevIL + - change your global include paths (eg. Tools->Options->Directories in MSVC6) + to include DevIL's include dirs (eg. D:\DevIL\ImageLib\Include) + - change your global library paths to include DevIL's include dirs + (eg. D:\DevIL\ImageLib\lib and D:\DevIL\ImageLib\lib\debug) + - change the post build steps as appropriate for your system + - uncomment IL_NO_GIF, IL_NO_JPG, IL_NO_MNG, IL_NO_PNG, IL_NO_TIF + - uncomment IL_NO_LCMS and comment out ilApplyProfile from IL.DEF + - comment out ILUT_USE_DIRECTX8 in il/ilut.h (I don't have it installed) + - comment out ilutD3D8LoadSurface ... ilutD3D8VolTexFromResource from ILUT.def + - change the USE_IMAGE_LIBRARY #define in ImageManager.cpp + + + + +REFERENCES +========== +[1] vCard, The Electronic Business Card Version 2.1 from Versit. + + +OUTSTANDING ISSUES +================== + +After Alpha-4, this section transferred to the SourceForge database. + + +THE TEST HARNESS +================ + +Running the test harness will produce a load of output similar to +the following: + +--tests//adhoc//straight_qp_4.vcf------------------------------------------ +Successfully read file 'tests//adhoc//straight_qp_4.vcf' +Successfully wrote file 'vobject.vcf' +Successfully wrote file 'tests//adhoc//straight_qp_4.out-1' + Sizes difference : + tests//adhoc//straight_qp_4.out-1 (139 bytes) Vs. + tests//adhoc//straight_qp_4.vcf (151 bytes) + Warning - differences after 1st read/write +Successfully read file 'tests//adhoc//straight_qp_4.out-1' +Successfully wrote file 'tests//adhoc//straight_qp_4.out-2' + OK - no differences after 2nd read/write + [60 tests, 0 errors, 13 warnings] + +What does it all mean? All the warnings are a result of size differences +between the original file & the result of reading/writing the file back. +The size differences are a result of: + * slightly different conventions for line length + * line ends (eg <LF> not <CR><LF>) + * different selection of quoted chars in QP format + * excess whitespace at the end of the file + * characters ignored before the first BEGIN: or between END: and BEGIN: + +Each such difference is clocked up as a warning. The [...] stuff is +a rolling count of tests, errors & warnings. An error is logged if +after the file is "canonicalised" (well; into the format assumed by +this library anyway) we fail to read & write and get the same output. + +The files in tests/spec are named after sections of the (very fine) +vcard 2.1 specification eg. 2_1_4_1-grouping-sequential.vcf will refer +to something like "sequential grouping" in section 2.1.4.1 of the +Versit doc (see http://www.imc.org/pdi/ for the docs). + +(There is no intention to infringe the copyright anyone might consider +they have vested in the text of these examples) + +The files in tests/adhoc are just sample scripts I knocked up +during development. + + +FUTURE PLANS +============ + +1) Convert this document to some decent on-line docs on the project website. + +2) Write a vobjects library .../src/vobjects & .../build/vobjectsl which + provides C++ classes modelling a vformat object with derived classes + for vCard, vNote etc. Functions on the base class provide file handling + and change logs. Functions on the derived classes handle a user's + normal interaction with the relevant objects eg: + + typedef enum + { + Work, + Home, + Cellular, + Mobile = Cellular + } + vf_phone_type_t; + + bool_t vformat::vcard::set_phone_no( + vf_phone_type_t t, /* Type of phone number */ + bool_t is_pref, /* Should this entry be given the PREF flag? */ + const char *phone_no /* The phone number itself */ + ); + +4) Duplicate the MFC app as a GTK app. + + + +CREDITS +======= + +Enjoy! + +Nick <Tilda@indigo8.freeserve.co.uk> diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..3292973 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,15 @@ +#!/bin/sh +gprefix=`which glibtoolize 2>&1 >/dev/null` +if [ $? -eq 0 ]; then + glibtoolize --force +else + libtoolize --force +fi +aclocal -I m4 +autoheader +automake --add-missing +autoconf + +if [ -z "$NOCONFIGURE" ]; then + ./configure "$@" +fi diff --git a/common/types.h b/common/types.h new file mode 100644 index 0000000..7eed375 --- /dev/null +++ b/common/types.h @@ -0,0 +1,87 @@ +/******************************************************************************* + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.5 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + In the abscence of suitable typedefs provided by whatever environment you're + building under, this defines the minimal set of types required by vformat library. + +MODIFICATION HISTORY + * $Log: types.h,v $ + * Revision 1.5 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.4 2002/10/08 20:23:16 tilda + * Improve comments. Tidy header. + * + * Revision 1.3 2002/10/08 20:20:10 tilda + * Comments (!). Removed unused types. + *******************************************************************************/ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#ifndef NORCSID +static const char _types_h_vss_id[] = "$Header: /cvsroot/vformat/src/common/types.h,v 1.5 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +#undef NULL +#define NULL 0 + +#undef FALSE +#define FALSE ((bool_t)(0)) + +#undef TRUE +#define TRUE ((bool_t)(1)) + +/*=============================================================================* + Public Types + *============================================================================*/ + +/* + * Basic types. + */ +#if defined(USE_INTTYPES_H) +#include <inttypes.h> +#else +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned long int uint32_t; +#endif + +/* + * Please avoide 'BOOL' (from Windows) and 'bool' (from C++) - vformat is used + * extensively in pure C embedded applications where neither are relevant. + */ +typedef unsigned char bool_t; + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_TYPES_H_*/ diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..54168ab --- /dev/null +++ b/config.h.in @@ -0,0 +1,87 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d1b1041 --- /dev/null +++ b/configure.ac @@ -0,0 +1,31 @@ +# Process this file with autoconf to produce a configure script. +AC_INIT(libvformat, 1.13, Nick <Tilda@indigo8.freeserve.co.uk>) +AC_CONFIG_SRCDIR([vf_iface.h]) +#AC_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE(libvformat, 1.13) +AM_CONFIG_HEADER(config.h) + +# Checks for programs. +# AC_PROG_CC + +# Checks for libraries. +AC_PROG_RANLIB +AC_PROG_LIBTOOL + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_MKTIME +AC_FUNC_STAT +AC_CHECK_FUNCS([atexit memset strstr]) + +AC_OUTPUT([Makefile src/Makefile vformat/Makefile test/Makefile doc/Makefile]) +AC_CONFIG_FILES([]) + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..57591c5 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,16 @@ +# No automatisation found. Write me if any idea. + +install-data-hook: + c2man -P "gcc -E -C -I.." ../vformat/vf_iface.h + + $(mkinstalldirs) $(mandir)/man3 + + for i in *.3; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(mandir)/man3/$$inst"; \ + $(INSTALL_DATA) $$file $(mandir)/man3/$$inst; \ + done diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..19b2d85 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,11 @@ +lib_LTLIBRARIES = libvformat.la + +libvformat_la_SOURCES = vf_access.c vf_malloc.c vf_strings.c vf_access_wrappers.c \ + vf_parser.c vf_writer.c vf_create_object.c \ + vf_access_calendar.c vf_reader.c vf_delete.c \ + vf_search.c vf_malloc_stdlib.c vf_modified.c vf_string_arrays.c + +EXTRA_DIST = *.h + +libvformat_la_LDFLAGS = -version-info 0 + diff --git a/src/vf_access.c b/src/vf_access.c new file mode 100644 index 0000000..7504150 --- /dev/null +++ b/src/vf_access.c @@ -0,0 +1,661 @@ +/**************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Revision: 1.23 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Core access functions for VF_OBJECT_Ts. The library includes other access + functions (see vf_access_wrappers.c) which are often just alternative slightly + higher level versions of what's found below. + + The intention is to provide a basic interface which covers all the required + functionality and also some quick'n'easy functions which can be used but don't + bloat the code (in a static library build anyway). + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access.c,v $ + * Revision 1.23 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.22 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.21 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.20 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.19 2002/10/08 21:45:06 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.18 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.17 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.16 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + * Revision 1.15 2001/11/18 21:45:58 tilda + * Ensure parameters changed to QP are updated correctly. + * + * Revision 1.14 2001/11/17 17:40:29 tilda + * Image / sound dialog box now works. + * + * Revision 1.13 2001/11/05 21:07:20 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.12 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.11 2001/10/24 05:30:39 tilda + * Start work on object create/modify API. + * + * Revision 1.10 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.9 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.8 2001/10/14 16:40:05 tilda + * Initial testing of access functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access.c,v 1.23 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" +#include "vf_modified.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +#define MAXINCREMENT (5) +#define MAXNUMTAGS (10) + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + +static bool_t strings_valid_index( + VPROP_T *p_vprop, /* The property */ + uint32_t n_string /* Index required */ + ); + +static bool_t ensure_value_encoding_tag( + VPROP_T *p_vprop, /* The property */ + vf_encoding_t encoding /* Encoding required */ + ); + +static bool_t set_prop_value_string( + VPROP_T *p_vprop, /* The property */ + uint32_t n_string, /* Index required */ + const char *p_string /* String required */ + ); + +static bool_t set_prop_value_base64( + VPROP_T *p_vprop, /* The property */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ); + + + + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name() + * + * DESCRIPTION + * Build the property name string in the indicated buffer. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void vf_get_prop_name( + VF_PROP_T *p_prop, /* The property */ + char *p_buffer, /* The buffer */ + uint32_t bufsize /* Size of the buffer */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + uint32_t i; + + if (p_vprop->p_group) + { + p_strcpy(p_buffer, p_vprop->p_group); + p_strcat(p_buffer, "."); + } + else + { + p_buffer[0] = '\0'; + } + + for (i = 0;i < p_vprop->name.n_strings;i++) + { + if (0 < i) + p_strcat(p_buffer, ";"); + + if (p_vprop->name.pp_strings[i]) + { + p_strcat(p_buffer, p_vprop->name.pp_strings[i]); + } + } +} + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_object_type() + * + * DESCRIPTION + * Return the type string identifying the indicated vformat object. + * + * RETURNS + * Ptr to string. + *---------------------------------------------------------------------------*/ + +const char *vf_get_object_type( + VF_OBJECT_T *p_object + ) +{ + const char *p_ret = NULL; + + if (p_object) + { + p_ret = ((VOBJECT_T *)p_object)->p_type; + } + + return p_ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value() + * + * DESCRIPTION + * Get hold of raw fields associated with the property. These are of + * various types: + * + * VF_ENC_VOBJECT + * - *pp_value = pointer to contained VF_OBJECT_T which can be + * passed back to any of the object manipulation functions. + * + * VF_ENC_7BIT, VF_ENC_QUOTEDPRINTABLE + * - *pp_value = ptr to array of char*, *p_size = number of elts. + * + * VF_ENC_8BIT, VF_BASE64 + * - *pp_value = ptr to bytes, *p_size = number of bytes + * + * RETURNS + * TRUE <=> encoding is valid, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_prop_value( + VF_PROP_T *p_prop, /* The property */ + void **pp_value, /* Pointer value */ + uint32_t *p_size, /* Integer value */ + vf_encoding_t *p_encoding /* Type of return values */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = TRUE; + + switch (p_vprop->value.encoding) + { + case VF_ENC_VOBJECT: + if (pp_value) + { + *pp_value = p_vprop->value.v.o.p_object; + } + break; + + case VF_ENC_7BIT: + case VF_ENC_QUOTEDPRINTABLE: + if (pp_value) + { + *pp_value = p_vprop->value.v.s.pp_strings; + } + if (p_size) + { + *p_size = p_vprop->value.v.s.n_strings; + } + break; + + case VF_ENC_8BIT: + case VF_ENC_BASE64: + if (pp_value) + { + *pp_value = p_vprop->value.v.b.p_buffer; + } + if (p_size) + { + *p_size = p_vprop->value.v.b.n_bufsize; + } + break; + + default: + ret = FALSE; + break; + } + + if (p_encoding) + { + *p_encoding = p_vprop->value.encoding; + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value() + * + * DESCRIPTION + * Set values associated with a property. + * + * Passing a value of encoding not the same as the current property + * encoding will cause the property contents to be freed prior to + * setting the indicated value. + * + * RETURNS + * TRUE <=> re-allocation success & encoding correct, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value( + VF_PROP_T *p_prop, /* The property */ + void *p_value, /* Pointer to the data */ + uint32_t n_param, /* Data size or index */ + vf_encoding_t encoding, /* Encoding in use */ + bool_t copy /* Copy the data? */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = TRUE; + + if (!copy) + return FALSE; + + if (encoding == p_vprop->value.encoding) + { + /* Leave it as is */ + } + else + { + delete_prop_contents(p_prop, FALSE); + + ensure_value_encoding_tag(p_vprop, encoding); + } + + switch (p_vprop->value.encoding) + { + case VF_ENC_VOBJECT: + { + if (p_vprop->value.v.o.p_object != p_value) + { + mark_property_modified(p_vprop, TRUE); + } + + p_vprop->value.v.o.p_object = p_value; + } + break; + + case VF_ENC_7BIT: + case VF_ENC_QUOTEDPRINTABLE: + { + ret = set_prop_value_string(p_vprop, n_param, p_value); + } + break; + + case VF_ENC_8BIT: + case VF_ENC_BASE64: + { + ret = set_prop_value_base64(p_vprop, p_value, n_param, copy); + } + break; + + default: + ret = FALSE; + break; + } + + return ret; +} + + + + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + + + + +/*---------------------------------------------------------------------------* + * NAME + * set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t set_prop_value_string( + VPROP_T *p_vprop, + uint32_t n_string, + const char *p_string + ) +{ + bool_t ret = FALSE; + + if (strings_valid_index(p_vprop, n_string)) + { + if ((p_vprop->value.v.s.pp_strings[n_string] && !p_string) || + (!p_vprop->value.v.s.pp_strings[n_string] && p_string) || + (p_vprop->value.v.s.pp_strings[n_string] && p_string && + p_stricmp(p_vprop->value.v.s.pp_strings[n_string], p_string))) + { + mark_property_modified(p_vprop, TRUE); + } + + ret = set_string_array_entry(&(p_vprop->value.v.s), p_string, n_string); + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t set_prop_value_base64( + VPROP_T *p_vprop, + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ) +{ + bool_t ret = FALSE; + + if (copy) + { + p_vprop->value.v.b.p_buffer = vf_malloc(length); + + if (p_vprop->value.v.b.p_buffer) + { + p_memcpy(p_vprop->value.v.b.p_buffer, p_data, length); + p_vprop->value.v.b.n_bufsize = length; + + ret = TRUE; + } + } + else + { + /* TBD */ + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * strings_valid_index() + * + * DESCRIPTION + * Check request for indicated string. If it's either in the current + * object or represents a reasonable exapansion the request is allowed. + * + * RETURNS + * TRUE <=> object can include indicated string. + *---------------------------------------------------------------------------*/ + +bool_t strings_valid_index( + VPROP_T *p_vprop, + uint32_t n_string + ) +{ + bool_t ret = FALSE; + + if (n_string < p_vprop->value.v.s.n_strings) + { + /* String in current extent of object */ + + ret = TRUE; + } + else + if ((p_vprop->value.v.s.n_strings <= n_string) && (n_string < p_vprop->value.v.s.n_strings + MAXINCREMENT)) + { + /* Set string within reasonable expansion of object */ + + void *p_tmp = vf_realloc(p_vprop->value.v.s.pp_strings, (1 + n_string) * sizeof(char *)); + + if (p_tmp) + { + uint32_t i; + + p_vprop->value.v.s.pp_strings = p_tmp; + + for (i = p_vprop->value.v.s.n_strings;i < (uint32_t)(1 + n_string);i++) + { + p_vprop->value.v.s.pp_strings[i] = NULL; + } + + p_vprop->value.v.s.n_strings = (1 + n_string); + + ret = TRUE; + } + } + else + { + /* Invalid request */ + } + + return ret; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * ensure_value_encoding_tag() + * + * DESCRIPTION + * Check/set encoding. + * + * RETURNS + * TRUE <=> encoding was set successfully. + *---------------------------------------------------------------------------*/ + +bool_t ensure_value_encoding_tag( + VPROP_T *p_vprop, + vf_encoding_t encoding + ) +{ + int n; + uint32_t i; + bool_t ret = TRUE; + + /* + * Locate the encoding value. + */ + for (i = 0, n = (-1);n == (-1) && (i < p_vprop->name.n_strings);i++) + { + const char *p_string = p_vprop->name.pp_strings[i]; + + if (p_string) + { + if (p_stristr(p_string, VFP_ENCODING) + || p_stristr(p_string, VFP_QUOTEDPRINTABLE) + || p_stristr(p_string, VFP_BASE64) + || p_stristr(p_string, VFP_8BIT) + || p_stristr(p_string, VFP_7BIT)) + { + n = i; + } + } + } + + /* + * Remove previous encoding + */ + if (0 <= n) + { + ret = set_string_array_entry(&(p_vprop->name), NULL, n); + } + + if (ret) + { + char *p_enc_string; + + switch (encoding) + { + case VF_ENC_QUOTEDPRINTABLE: + p_enc_string = VFP_QUOTEDPRINTABLE; + break; + + case VF_ENC_BASE64: + p_enc_string = VFP_BASE64; + break; + + default: + p_enc_string = NULL; + } + + if (p_enc_string) + { + if ((-1) == n) + { + ret = add_string_to_array(&(p_vprop->name), p_enc_string); + } + else + { + ret = set_string_array_entry(&(p_vprop->name), p_enc_string, n); + } + } + } + + if (ret) + { + p_vprop->value.encoding = encoding; + } + + return ret; +} + + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_access_calendar.c b/src/vf_access_calendar.c new file mode 100644 index 0000000..159c432 --- /dev/null +++ b/src/vf_access_calendar.c @@ -0,0 +1,528 @@ +/**************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_access.c $ + $Revision: 1.7 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Wrappers on the core access functions & other utility functions. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access_calendar.c,v $ + * Revision 1.7 2002/11/24 14:26:22 tilda + * IID484686 - More vcard work. + * + * Revision 1.6 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.5 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.4 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.3 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.2 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.1 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_calendar_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access_calendar.c,v 1.7 2002/11/24 14:26:22 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +#include <time.h> +#include <stdio.h> +#include <ctype.h> + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +#define ISO8061_TOKEN_YEARS 'Y' +#define ISO8061_TOKEN_MONTHS 'M' +#define ISO8061_TOKEN_WEEKS 'W' +#define ISO8061_TOKEN_DAYS 'D' +#define ISO8061_TOKEN_HOURS 'H' +#define ISO8061_TOKEN_MINUTES 'M' +#define ISO8061_TOKEN_SECONDS 'S' + +#define ISO8061_TOKEN_TIME 'T' +#define ISO8061_TOKEN_PERIOD 'P' + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + +static void append_iso8061_value(char *p_string, uint32_t value, char symbol); +static void append_iso8061_tag(char *p_string, char symbol); + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_time() + * + * DESCRIPTION + * Set a time_t value into a VF property. + * + * RETURNS + * TRUE iff property added & set OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're encoding to */ + const time_t t_value /* Time value */ + ) +{ + bool_t ret; + struct tm *p_tm; + + p_tm = localtime(&t_value); + + if (p_tm) + { + char value[256]; + + if (p_tm->tm_hour || p_tm->tm_min || p_tm->tm_sec) + { + sprintf(value, "%4d%02d%02dT%02d%02d%02d", + 1900 + p_tm->tm_year, + 1 + p_tm->tm_mon, + p_tm->tm_mday, + p_tm->tm_hour, + p_tm->tm_min, + p_tm->tm_sec); + } + else + { + sprintf(value, "%4d%02d%02d", + 1900 + p_tm->tm_year, + 1 + p_tm->tm_mon, + p_tm->tm_mday); + } + + ret = vf_set_prop_value_string(p_prop, n_string, value); + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_time() + * + * DESCRIPTION + * Fetch a time_t value from a VF property. + * + * RETURNS + * TRUE iff foudn & converted OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're decoding */ + time_t *p_t_value /* Pointer to output time value */ + ) +{ + bool_t ret; + const char *p_value; + + p_value = vf_get_prop_value_string(p_prop, n_string); + + if (p_value) + { + ret = vf_date_string_to_time(p_t_value, p_value); + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_date_string_to_time() + * + * DESCRIPTION + * Convert calendar string to absolute time. The basic formats are + * 19960401, 19960401T073000Z + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_date_string_to_time( + uint32_t *p_time, /* Output time value */ + const char *p_string /* Input string */ + ) +{ + bool_t ret = FALSE; + + if (p_string && p_time) + { + time_t t; + struct tm tm; + + p_memset(&tm, '\0', sizeof(tm)); + + /* + * p_string[8] is either 'T' or '\0' or an error. + */ + + if (ISO8061_TOKEN_TIME == p_string[8]) + { + if (6 == sscanf(p_string, "%4d%2d%2dT%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)) + { + if ((1970 <= tm.tm_year) && + ((1 <= tm.tm_mon) && (tm.tm_mon <= 12)) && + ((1 <= tm.tm_mday) && (tm.tm_mday <= 28)) && + ((0 <= tm.tm_hour) && (tm.tm_hour <= 23)) && + ((0 <= tm.tm_min) && (tm.tm_hour <= 59)) && + ((0 <= tm.tm_sec) && (tm.tm_sec <= 59))) + { + ret = TRUE; + } + } + } + else + if ('\0' == p_string[8]) + { + if (3 == sscanf(p_string, "%4d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday)) + { + if ((1970 <= tm.tm_year) && + ((1 <= tm.tm_mon) && (tm.tm_mon <= 12)) && + ((1 <= tm.tm_mday) && (tm.tm_mday <= 28))) + { + ret = TRUE; + } + } + } + else + { + /* Nor flesh nor fish nor fowl */ + } + + /* + * Reduce the year value to correct range & convert to time_t. + */ + + if (ret) + { + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = -1; + + t = mktime(&tm); + + if ((-1) == t) + { + ret = FALSE; + } + else + { + *p_time = (uint32_t)t; + } + } + } + + return ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_string_to_time() + * + * DESCRIPTION + * Convert period definition string to time value. The format is + * P[aaaY][bbbM][cccW][dddD]T[eeeH][fffM][gggS] where 'aaa' is a + * number of years, bbb months etc. + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_period_string_to_time( + VF_ISO8601_PERIOD_T *p_period, /* Output time value */ + const char *p_string /* Input string */ + ) +{ + bool_t ret = TRUE; + bool_t in_time_part = FALSE; + + p_memset(p_period, '\0', sizeof(*p_period)); + + if (p_string && ('P' == p_string[0]) && *(++p_string)) + { + while (ret && *p_string) + { + uint32_t value = 0; + + while (isdigit((int)*p_string)) + { + value = (value * 10) + *(p_string++) - '0'; + } + + switch (*p_string++) + { + case '\0': + { + ret = FALSE; + } + break; + + case ISO8061_TOKEN_YEARS: + { + p_period->years = value; + } + break; + + case ISO8061_TOKEN_MONTHS: + /*case ISO8061_TOKEN_MINUTES:*/ + { + if (in_time_part) + { + p_period->minutes = value; + } + else + { + p_period->months = value; + } + } + break; + + case ISO8061_TOKEN_WEEKS: + { + p_period->weeks = value; + } + break; + + case ISO8061_TOKEN_DAYS: + { + p_period->days = value; + } + break; + + case ISO8061_TOKEN_TIME: + { + if (in_time_part) + { + ret = FALSE; + } + else + { + in_time_part = TRUE; + } + } + break; + + case ISO8061_TOKEN_HOURS: + { + p_period->hours = value; + } + break; + + case ISO8061_TOKEN_SECONDS: + { + p_period->seconds = value; + } + break; + + default: + { + ret = FALSE; + } + break; + } + } + } + else + { + ret = FALSE; + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_time_to_string() + * + * DESCRIPTION + * Convert a VF_ISO8601_PERIOD_T to a string. + * + * RETURNS + * Number of characters written. + *---------------------------------------------------------------------------*/ + +uint32_t vf_period_time_to_string( + char *p_string, /* Output string */ + const VF_ISO8601_PERIOD_T *p_period /* Input period value */ + ) +{ + uint32_t ret = 0; + + if (p_string && p_period) + { + p_string[0] = '\0'; + + append_iso8061_tag(p_string, ISO8061_TOKEN_PERIOD); + + append_iso8061_value(p_string, p_period->years, ISO8061_TOKEN_YEARS); + append_iso8061_value(p_string, p_period->months, ISO8061_TOKEN_MONTHS); + append_iso8061_value(p_string, p_period->weeks, ISO8061_TOKEN_WEEKS); + append_iso8061_value(p_string, p_period->days, ISO8061_TOKEN_DAYS); + + if (p_period->hours || p_period->minutes || p_period->seconds) + { + append_iso8061_tag(p_string, ISO8061_TOKEN_TIME); + } + + append_iso8061_value(p_string, p_period->hours, ISO8061_TOKEN_HOURS); + append_iso8061_value(p_string, p_period->minutes, ISO8061_TOKEN_MINUTES); + append_iso8061_value(p_string, p_period->seconds, ISO8061_TOKEN_SECONDS); + + ret = p_strlen(p_string); + } + + return ret; +} + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + + + +/*---------------------------------------------------------------------------* + * NAME + * append_iso8061_value() + * + * DESCRIPTION + * Append xxxY value to the current encoded string. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void append_iso8061_value(char *p_string, uint32_t value, char symbol) +{ + if (value) + { + sprintf(p_string + p_strlen(p_string), "%lu%c", (unsigned long)value, symbol); + } +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * append_iso8061_tag() + * + * DESCRIPTION + * Append indicated character to string. + * + * RETURNS + * (none). + *---------------------------------------------------------------------------*/ + +void append_iso8061_tag(char *p_string, char symbol) +{ + p_string += p_strlen(p_string); + + *p_string++ = symbol; + *p_string++ = '\0'; +} + + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_access_wrappers.c b/src/vf_access_wrappers.c new file mode 100644 index 0000000..2eea457 --- /dev/null +++ b/src/vf_access_wrappers.c @@ -0,0 +1,541 @@ +/**************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_access.c $ + $Revision: 1.16 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Wrappers on the core access functions & other utility functions. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access_wrappers.c,v $ + * Revision 1.16 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.15 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.14 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.10 2001/11/18 22:07:02 tilda + * Ensure empty BASE64 properties get the encoding set correctly. + * + * Revision 1.9 2001/11/18 21:48:18 tilda + * Remove redundant code. + * + * Revision 1.8 2001/11/17 17:40:29 tilda + * Image / sound dialog box now works. + * + * Revision 1.7 2001/11/16 22:34:50 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.6 2001/11/15 08:56:06 tilda + * Fix bug in qualifier location code. + * + * Revision 1.5 2001/11/14 22:36:56 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.4 2001/11/14 16:05:06 tilda + * Extend capabilities of vf_find_prop_qual_index(). + * + * Revision 1.3 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_wrappers_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access_wrappers.c,v 1.16 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + +bool_t vf_prop_belongs_to_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_string() + * + * DESCRIPTION + * Obtain string pointer value from VF_PROP_T. If the array contains + * an entry for the indicated string return it. Return NULL if out of + * range request, ie. n_string=3 for N=0;1;2 + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +char *vf_get_prop_value_string( + VF_PROP_T *p_prop, + uint32_t n_string + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *p_ret = NULL; + + if (p_vprop->value.v.s.pp_strings) + { + if (n_string < p_vprop->value.v.s.n_strings) + { + p_ret = p_vprop->value.v.s.pp_strings[n_string]; + } + } + + return p_ret; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_string( + VF_PROP_T *p_prop, + uint32_t n_string, + const char *p_string + ) +{ + return vf_set_prop_value(p_prop, (char *)p_string, n_string, VF_ENC_7BIT, TRUE); +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_base64() + * + * DESCRIPTION + * Obtain data pointer for BASE64 data. + * + * RETURNS + * Pointer to data. + *---------------------------------------------------------------------------*/ + +const uint8_t *vf_get_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t *p_length /* Length of the binary data */ + ) +{ + const uint8_t *p_return = NULL; + + if (p_prop) + { + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + p_return = p_vprop->value.v.b.p_buffer; + + if (p_length) + { + *p_length = p_vprop->value.v.b.n_bufsize; + } + } + + return p_return; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ) +{ + return vf_set_prop_value(p_prop, (char *)p_data, length, VF_ENC_BASE64, copy); +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_object() + * + * DESCRIPTION + * Obtain object pointer value from VF_PROP_T. + * + * RETURNS + * Pointer to vobject value (or NULL if not found). + *---------------------------------------------------------------------------*/ + +VF_OBJECT_T *vf_get_prop_value_object( + VF_PROP_T *p_prop + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + if (VF_ENC_VOBJECT == p_vprop->value.encoding) + { + return (VF_OBJECT_T *)(p_vprop->value.v.o.p_object); + } + + return NULL; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_object() + * + * DESCRIPTION + * Set the value of the indicated property to be a VOBJECT. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = FALSE; + + /* + * Avoid various sillies. + */ + if (p_prop && p_object && !vf_prop_belongs_to_object(p_prop, p_object)) + { + delete_prop_contents(p_prop, FALSE); + + p_vprop->value.v.o.p_object = (VOBJECT_T *)p_object; + p_vprop->value.encoding = VF_ENC_VOBJECT; + } + + return TRUE; +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name_string() + * + * DESCRIPTION + * Get n'th name string. + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +char *vf_get_prop_name_string( + VF_PROP_T *p_prop, + uint32_t n_string + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *p_ret = NULL; + + if (p_vprop->name.pp_strings) + { + if (n_string < p_vprop->name.n_strings) + { + p_ret = p_vprop->name.pp_strings[n_string]; + } + } + + return p_ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_name_string() + * + * DESCRIPTION + * Set n'th name string. + * + * RETURNS + * TRUE iff allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_name_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ) +{ + VPROP_T *p_vprop; + bool_t ret = FALSE; + + p_vprop = (VPROP_T *)p_prop; + + if (p_vprop) + { + if ((-1) == n_string) + { + ret = add_string_to_array(&p_vprop->name, p_string); + } + else + { + ret = set_string_array_entry(&p_vprop->name, p_string, n_string); + } + } + + return TRUE; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_find_prop_qual_index() + * + * DESCRIPTION + * Locate property qualifier given either an array of possible values + * or a single token that is either present or absent. For example + * if we have a property: + * + * NAME;THIRD;TIME;LUCKY:VALUE1;VALUE2;VALUE3 + * + * Then there are two possible searches. + * + * Firstly we can look for the property qualifier which can take values + * from the array { "FIRST", "SECOND", THIRD" } in which case the array + * is passed as pp_possible_values and the function returns with the + * values *p_found_value_index=2, p_qualifier_index=1 + * + * Secondly we can look for the token with value "TIME" in which case + * p_token is set to "TIME" and the function returns *p_qualifier_index=2. + * + * RETURNS + * TRUE iff found, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_find_prop_qual_index( + VF_PROP_T *p_prop, /* The property we're querying */ + uint32_t *p_qualifier_index, /* Ptr to output name index */ + uint32_t *p_found_value_index, /* Ptr to output index in array */ + const char **pp_possible_values, /* Array of possible values */ + const char *p_token, /* Token searched for */ + vf_search_flags_t match /* String comparison flags */ + ) +{ + uint32_t n; + bool_t ret; + + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + for (n = 0, ret = FALSE;!ret && (n < p_vprop->name.n_strings);n++) + { + const char *p_string = p_vprop->name.pp_strings[n]; + + if (p_string) + { + if (pp_possible_values) + { + uint32_t i; + + for (i = 0;!ret && pp_possible_values[i];i++) + { + if (0 == p_stricmp(pp_possible_values[i], p_string)) + { + if (p_found_value_index) + *p_found_value_index = i; + if (p_qualifier_index) + *p_qualifier_index = n; + + ret = TRUE; + } + } + } + else + if (p_token) + { + if (0 == p_stricmp(p_token, p_string)) + { + if (p_qualifier_index) + *p_qualifier_index = n; + + ret = TRUE; + } + } + else + { + /*???*/ + } + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_find_charset() + * + * DESCRIPTION + * Locate the charset + * + * RETURNS + * vf_charset_t. + *---------------------------------------------------------------------------*/ + +const char *vf_find_charset( + VF_PROP_T *p_prop + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *ret; + + if (!string_array_contains_string(&p_vprop->name, &ret, -1, VFP_CHARSET, FALSE)) + { + ret = NULL; + } + else + { + ret += 1 + p_strlen(VFP_CHARSET); + } + + return ret; +} + + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + +bool_t vf_prop_belongs_to_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ) +{ + return FALSE; +} + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_config.h b/src/vf_config.h new file mode 100644 index 0000000..2a4ff8f --- /dev/null +++ b/src/vf_config.h @@ -0,0 +1,85 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_common.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Common header file for vformat library. This file is internal to vformat + (ie. changes here don't affect the interface) but contains the definitions + which affect the operation of various components eg. the memory debug. + + This file is #included before all other header files within the library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_config.h,v $ + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + * + *******************************************************************************/ + +#ifndef _VF_CONFIG_H_ +#define _VF_CONFIG_H_ + +#ifndef NORCSID +static const char vf_config_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_config.h,v 1.1 2002/10/26 15:57:11 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +/* + * If building debug version under windows then include the memory debug interface. + */ +#if (defined(WIN) || defined(WIN32)) && defined(_DEBUG) +#if !defined(VFORMAT_MEM_DEBUG) +#define VFORMAT_MEM_DEBUG +#endif +#endif + +/* + * Conditional compiles allowing configuration of various string portability functions. + */ +/* #define HAVE_STRLEN */ +/* #define HAVE_STRCPY */ +/* #define HAVE_STRCMP */ +/* #define HAVE_STRCAT */ +/* #define HAVE_STRSTR */ +/* #define HAVE_STRICMP */ +/* #define HAVE_MEMCPY */ +/* #define HAVE_MEMSET */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_CONFIG_H_*/ diff --git a/src/vf_create_object.c b/src/vf_create_object.c new file mode 100644 index 0000000..ab540b9 --- /dev/null +++ b/src/vf_create_object.c @@ -0,0 +1,158 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Revision: 1.8 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + The vf_create_object() function. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_create_object.c,v $ + * Revision 1.8 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.7 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.6 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.5 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.4 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.3 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.2 2002/01/06 13:11:55 tilda + * Update header. + * + * Revision 1.1 2002/01/06 13:08:15 tilda + * Change file name from vf_createobject.c + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_create_object_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_create_object.c,v 1.8 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *===========================================================================*/ + +#include <common/types.h> + +/*===========================================================================* + Interface Header Files + *==========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *==========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data Types + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *==========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_create_object() + * + * DESCRIPTION + * Creates and empty vformat object. + * + * RETURNS + * Ptr to object if created else NULL. + *---------------------------------------------------------------------------*/ + +VF_OBJECT_T *vf_create_object( + const char *p_type, /* Type of object to create */ + VF_OBJECT_T *p_parent /* Parent object if any */ + ) +{ + VOBJECT_T *p_new = NULL; + + if (p_type) + { + p_new = vf_malloc(sizeof(VOBJECT_T)); + + if (p_new) + { + p_memset(p_new, '\0', sizeof(VOBJECT_T)); + + p_new->p_type = vf_malloc(1 + p_strlen(p_type)); + + p_new->p_parent = (VOBJECT_T *)p_parent; + + if (p_new->p_type) + { + p_strcpy(p_new->p_type, p_type); + } + else + { + vf_free(p_new); + p_new = NULL; + } + } + } + + return (VF_OBJECT_T *)p_new; +} + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ +/* None */ + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_delete.c b/src/vf_delete.c new file mode 100644 index 0000000..d70b8e4 --- /dev/null +++ b/src/vf_delete.c @@ -0,0 +1,327 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_delete.c $ + $Revision: 1.14 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Delete a vformat object. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_delete.c,v $ + * Revision 1.14 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.10 2001/11/05 21:07:20 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.9 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_delete_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_delete.c,v 1.14 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include <common/types.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +static void free_prop_list( + VPROP_T *p_props /* List of properties to free */ + ); + + + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_object() + * + * DESCRIPTION + * Cleans up the memory used by the indicated vformat object. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_delete_object( + VF_OBJECT_T *p_object, + bool_t all + ) +{ + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + + if (p_obj) + { + VOBJECT_T *p_next = p_obj->p_next; + + free_prop_list(p_obj->p_props); + + if (p_obj->p_type) + { + vf_free(p_obj->p_type); + } + + vf_free(p_obj); + + if (all ) + { + vf_delete_object((VF_OBJECT_T *)p_next, TRUE); + } + } +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_prop() + * + * DESCRIPTION + * Deletes indicated property from the indicated object. Deletes prop + * contents if dc is set. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_delete_prop( + VF_OBJECT_T *p_object, /* The object we're deleting from */ + VF_PROP_T *p_prop, /* The property we're removing */ + bool_t dc /* Should property contents be deleted? */ + ) +{ + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + + if (p_obj) + { + VPROP_T **p_vprop = &(p_obj->p_props); + + while (*p_vprop) + { + if ((*p_vprop) == (VPROP_T *)p_prop) + { + *p_vprop = ((VPROP_T *)p_prop)->p_next; + + if (dc) + { + delete_prop_contents(p_prop, TRUE); + } + + vf_free(p_prop); + + break; + } + else + { + p_vprop = &((*p_vprop)->p_next); + } + } + } +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * delete_prop_contents() + * + * DESCRIPTION + * Cleans up the memory used by the value associated with the property. + * The property is not deleted => can be a statically allocated variable. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void delete_prop_contents( + VF_PROP_T *p_vprop, /* The VF_PROP_T to clean */ + bool_t delname /* Delete the name as well? */ + ) +{ + VPROP_T *p_prop = (VPROP_T *)p_vprop; + + if (delname) + { + free_string_array_contents(&p_prop->name); + + if (p_prop->p_group) + { + vf_free(p_prop->p_group); + p_prop->p_group = NULL; + } + } + + if (p_prop->value.v.b.p_buffer) + { + vf_free(p_prop->value.v.b.p_buffer); + p_prop->value.v.b.p_buffer = NULL; + } + + if (p_prop->value.v.s.pp_strings) + { + uint32_t n; + + for (n = 0;n < p_prop->value.v.s.n_strings;n++) + { + if (p_prop->value.v.s.pp_strings[n]) + { + vf_free(p_prop->value.v.s.pp_strings[n]); + p_prop->value.v.s.pp_strings[n] = NULL; + } + } + + vf_free(p_prop->value.v.s.pp_strings); + p_prop->value.v.s.pp_strings = NULL; + + p_prop->value.v.s.n_strings = 0; + } + + if (p_prop->value.v.o.p_object) + { + vf_delete_object((VF_OBJECT_T *)p_prop->value.v.o.p_object, TRUE); + p_prop->value.v.o.p_object = NULL; + } +} + + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * free_prop_list() + * + * DESCRIPTION + * Cleans up the memory used by the indicated property list. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void free_prop_list( + VPROP_T *p_props /* List of properties to free */ + ) +{ + VPROP_T *p_tmp; + + for (p_tmp = p_props;p_tmp;) + { + VPROP_T *p_next = p_tmp->p_next; + + delete_prop_contents((VF_PROP_T *)p_tmp, TRUE); + + vf_free(p_tmp); + + p_tmp = p_next; + } +} + + + + + + + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_internals.h b/src/vf_internals.h new file mode 100644 index 0000000..98ddacc --- /dev/null +++ b/src/vf_internals.h @@ -0,0 +1,223 @@ +/******************************************************************************* + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_internals.h $ + $Revision: 1.15 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Definition of the internal representation used for VOBJECTs. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_internals.h,v $ + * Revision 1.15 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.14 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.10 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.9 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.8 2001/10/14 16:40:04 tilda + * Initial testing of access functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef _VF_INTERNALS_H_ +#define _VF_INTERNALS_H_ + +#ifndef NORCSID +static const char vf_internals_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_internals.h,v 1.15 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +#define VFP_BEGIN "BEGIN" +#define VFP_END "END" + +/*=============================================================================* + Public Types + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VSTRARRAY_T encapsulates an array of strings. + *----------------------------------------------------------------------------*/ + +typedef struct VSTRARRAY_T +{ + uint32_t n_strings; /* Then number of strings */ + char **pp_strings; /* The strings */ +} +VSTRARRAY_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VBINDATA_T encapsulates a chunk of binary data. Yes, you could encode + * any and all vformat attributes in BASE64 but custom is to use BASE64 + * for images etc. + *----------------------------------------------------------------------------*/ + +typedef struct VBINDATA_T +{ + char *p_buffer; /* Binary data */ + uint32_t n_bufsize; +} +VBINDATA_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VOBJDATA_T + *----------------------------------------------------------------------------*/ + +typedef struct VOBJDATA_T +{ + struct VOBJECT_T *p_object; /* Another vformat object */ +} +VOBJDATA_T; + + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VPROPVALUE_T encapsulates the "value" half of a property. + *----------------------------------------------------------------------------*/ + +typedef struct VPROPVALUE_T +{ + vf_encoding_t encoding; + + struct + { + VSTRARRAY_T s; + VBINDATA_T b; + VOBJDATA_T o; + } + v; +} +VPROPVALUE_T; + + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VPROP_T defines a single property. It's an association of a name + * and value pair. A vformat object is simply a list of properties. + * Associated with a property is (possibly) a group name. + *----------------------------------------------------------------------------*/ + +typedef struct VPROP_T +{ + char *p_group; /* Group - we keep the A.B.C format */ + VSTRARRAY_T name; /* Name fields */ + VPROPVALUE_T value; /* Value fields */ + + struct VPROP_T *p_next; /* Next property */ + struct VPROP_T *p_next_srch; /* Next in current search */ + + bool_t modified; /* Property modified? */ + + struct VOBJECT_T *p_parent; /* Owning object (if any) */ +} +VPROP_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VOBJECT_T defines a single vformat object. + *----------------------------------------------------------------------------*/ + +typedef struct VOBJECT_T +{ + char *p_type; /* "VCARD" or "VCALENDAR" etc. */ + VPROP_T *p_props; /* List of properties */ + + bool_t modified; /* Object modified? */ + + struct VOBJECT_T *p_parent; /* Owning object (if any) */ + struct VOBJECT_T *p_next; /* Next object (if any) */ +} +VOBJECT_T; + + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * delete_prop_contents() + * + * DESCRIPTION + * Cleans up the memory used by the value associated with the property. + * The property is not deleted => can be a statically allocated variable. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern void delete_prop_contents( + VF_PROP_T *p_vprop, /* The VF_PROP_T to clean */ + bool_t delname /* Delete the name as well? */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_INTERNALS_H_*/ + diff --git a/src/vf_malloc.c b/src/vf_malloc.c new file mode 100644 index 0000000..ef405d9 --- /dev/null +++ b/src/vf_malloc.c @@ -0,0 +1,270 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_malloc.c $ + $Revision: 1.7 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Implements the memory allocation functions used by the rest of the vformat + library, defaulting to the functions provided by vf_malloc_stdlib.c which + uses malloc() etc. + + Code below knows nothing about the specific allocation scheme in use or it's + debugging facilities and is simply provides the common functions and the + ability to point vformat at an alternative allocation module. + + The only conditional compile option recognised is VFORMAT_MEM_DEBUG which + is described in the accompanying header file. + + Note + ==== + The original code merged the malloc() implementation with the debug facility + and also included a conditional compile VFORMAT_EXT_MALLOC to control the use + of external allocation functions. Given that this tripped up the _author_ on + at least one public test event (UPF-9, where the sync engine was unable to read + VCARDS & extract the X-IRMC stuff) it was considered overcomplicated and has + been considerably simplified ;) - T. + +MODIFICATION HISTORY + * $Log: vf_malloc.c,v $ + * Revision 1.7 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.6 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.5 2002/10/08 21:08:43 tilda + * Improve memory debugging functions. + * + * Revision 1.4 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_malloc_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc.c,v 1.7 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#if !defined(VFORMAT_EXCLUDE_MALLOC) +#include "vf_malloc_stdlib.h" +#endif + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ + +/* + * Pointers to the functions in use - initialised to the default CRT based allocation + * functions unless VFORMAT_EXCLUDE_MALLOC is set in which case they are initialised + * to NULL in the expectation that the user calls vf_set_mem_functions() at some point. + */ + +#if defined(VFORMAT_EXCLUDE_MALLOC) +static vf_malloc_fn_t vf_malloc_fn; +static vf_realloc_fn_t vf_realloc_fn; +static vf_free_fn_t vf_free_fn; +#else +static vf_malloc_fn_t vf_malloc_fn = _vf_stdlib_malloc; +static vf_realloc_fn_t vf_realloc_fn = _vf_stdlib_realloc; +static vf_free_fn_t vf_free_fn = _vf_stdlib_free; +#endif + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_set_mem_functions() + * + * DESCRIPTION + * Set the memory allocation functions we're using. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_set_mem_functions( + vf_malloc_fn_t malloc_fn, /* Allocation function */ + vf_realloc_fn_t realloc_fn, /* Reallocation function */ + vf_free_fn_t free_fn /* Free function */ + ) +{ + vf_realloc_fn = realloc_fn; + vf_malloc_fn = malloc_fn; + vf_free_fn = free_fn; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_malloc() + * + * DESCRIPTION + * Allocate chunk of memory. + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_malloc( + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + void *p = NULL; + + if (vf_malloc_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + p = vf_malloc_fn(s, file, line); +#else + p = vf_malloc_fn(s); +#endif + } + + return p; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_realloc() + * + * DESCRIPTION + * Re-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_realloc( + void *p, /* Original pointer */ + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* filename */ + int line /* line number */ +#endif + ) +{ + void *np = NULL; + + if (vf_realloc_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + np = vf_realloc_fn(p, s, file, line); +#else + np = vf_realloc_fn(p, s); +#endif + } + + return np; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_free() + * + * DESCRIPTION + * De-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void _vf_free( + void *p /* Pointer */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + if (vf_free_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + vf_free_fn(p, file, line); +#else + vf_free_fn(p); +#endif + } +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_malloc.h b/src/vf_malloc.h new file mode 100644 index 0000000..7116d64 --- /dev/null +++ b/src/vf_malloc.h @@ -0,0 +1,166 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_malloc.h $ + $Revision: 1.6 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Memory allocation functions / macros for vformat code. The code always uses + vf_malloc(), vf_realloc() and vf_free() which are replaced by macros with the + names of functions implemented in vf_malloc.c. + + If the conditional compile VFORMAT_MEM_DEBUG is set then in addition to the + caller's allocation parameters, filename and line number information is + provided to the lower layer which may record this for debugging. + + Additionally, a function vf_set_mem_functions() is provided which allows an + application to replace the allocation functions with it's own. This should + be done before vformat allocates any memory ie. during initialisation. + + Unless the library is built with the symbol VFORMAT_EXCLUDE_MALLOC defined + then the library defaults to using malloc() etc. + +MODIFICATION HISTORY + * $Log: vf_malloc.h,v $ + * Revision 1.6 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.5 2002/10/08 21:08:43 tilda + * Improve memory debugging functions. + * + * Revision 1.4 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef _VF_MALLOC_H_ +#define _VF_MALLOC_H_ + +#ifndef NORCSID +static const char vf_malloc_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc.h,v 1.6 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +/* + * If VFORMAT_MEM_DEBUG is defined, map the vf_xxx() allocation calls to + * the debugging versions found in vf_malloc.c + */ + +#if defined(VFORMAT_MEM_DEBUG) + +#define vf_malloc(x) _vf_malloc(x, __FILE__, __LINE__) +#define vf_realloc(x, y) _vf_realloc(x, y, __FILE__, __LINE__) +#define vf_free(x) _vf_free(x, __FILE__, __LINE__) + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + +#define vf_malloc(x) _vf_malloc(x) +#define vf_realloc(x, y) _vf_realloc(x, y) +#define vf_free(x) _vf_free(x) + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + +/*=============================================================================* + Public Types + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) + +typedef void *(*vf_malloc_fn_t)(uint32_t s, const char *file, int line); +typedef void *(*vf_realloc_fn_t)(void *p, uint32_t ns, const char *file, int line); +typedef void (*vf_free_fn_t)(void *p, const char *file, int line); + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + +typedef void *(*vf_malloc_fn_t)(uint32_t s); +typedef void *(*vf_realloc_fn_t)(void *p, uint32_t ns); +typedef void (*vf_free_fn_t)(void *p); + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_malloc(), _vf_realloc(), _vf_free() + * + * DESCRIPTION + * Memory allocation functions in use. If VFORMAT_MEM_DEBUG is defined + * the line & file are recorded as well. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +#if defined(VFORMAT_MEM_DEBUG) + +extern void *_vf_malloc(uint32_t s, const char *file, int line); +extern void *_vf_realloc(void *p, uint32_t ns, const char *file, int line); +extern void _vf_free(void *p, const char *file, int line); + +#else + +extern void *_vf_malloc(uint32_t s); +extern void *_vf_realloc(void *p, uint32_t ns); +extern void _vf_free(void *p); + +#endif + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_set_mem_functions() + * + * DESCRIPTION + * Set the memory allocation functions we're using. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_set_mem_functions( + vf_malloc_fn_t malloc_fn, + vf_realloc_fn_t realloc_fn, + vf_free_fn_t free_fn + ); + + + + +/*=============================================================================* + FIN + *============================================================================*/ + +#endif /*_VF_MALLOC_H_*/ diff --git a/src/vf_malloc_stdlib.c b/src/vf_malloc_stdlib.c new file mode 100644 index 0000000..6318fa5 --- /dev/null +++ b/src/vf_malloc_stdlib.c @@ -0,0 +1,392 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_malloc.c $ + $Revision: 1.2 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + C standard library based memory allocation functions referenced by default in + the accompanying vf_malloc.c file. These are excluded from the build entirely + if VFORMAT_EXCLUDE_MALLOC is set in the build options. + +MODIFICATION HISTORY + * $Log: vf_malloc_stdlib.c,v $ + * Revision 1.2 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#if !defined(VFORMAT_EXCLUDE_MALLOC) + +#ifndef NORCSID +static const char vf_malloc_stdlib_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc_stdlib.c,v 1.2 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +#include <stdlib.h> +#include <stdio.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define NUMMEMBLOCKS (1024) + +#if defined(WIN) || defined(WIN32) +#define DEBUGBREAK _asm { int 3 } +#endif + +#ifndef DEBUGBREAK +#define DEBUGBREAK +#endif + +#define ALLOCBREAK (-1) + +/*============================================================================* + Private Data Types + *============================================================================*/ + +typedef struct MEMBLOCK_T +{ + void *p; /* The block */ + uint32_t s; /* The size */ + char *file; /* filename it was allocated in */ + int line; /* line number */ +} +MEMBLOCK_T; + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) +static void init_mem_debug(void); +static void atexit_dump_mem(void); +#endif + +/*============================================================================* + Private Data + *============================================================================*/ + +static MEMBLOCK_T blocks[NUMMEMBLOCKS]; + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_malloc() + * + * DESCRIPTION + * vformat compatible memory allocator using C standard library functions. + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_stdlib_malloc( + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* filename */ + int line /* line number */ +#endif + ) +{ + void *p = NULL; + +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p) + { + } + else + { + p = malloc(s); + + if (p) + { + blocks[i].p = p; + blocks[i].s = s; + blocks[i].file = (char *)file; + blocks[i].line = line; + } + + if (i == ALLOCBREAK) + { + DEBUGBREAK; + } + + break; + } + } + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + + p = malloc(s); + +#endif + + return p; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_realloc() + * + * DESCRIPTION + * Re-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_stdlib_realloc( + void *p, /* Original pointer */ + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + void *np = NULL; + +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + if (!p) + return _vf_stdlib_malloc(s, file, line); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p == p) + { + np = realloc(p, s); + + if (np) + { + blocks[i].p = np; + blocks[i].s = s; + } + + break; + } + } + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + + np = realloc(p, s); + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + + return np; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_free() + * + * DESCRIPTION + * De-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void _vf_stdlib_free( + void *p /* Pointer */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p == p) + { + blocks[i].p = NULL; + blocks[i].s = 0; + blocks[i].line = 0; + blocks[i].file = NULL; + + free(p); + + break; + } + } + +#else + + free(p); + +#endif +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_stdlib_dump_alloc_info() + * + * DESCRIPTION + * Display current state of memory allocator. + * + * RETURNS + * TRUE if blocks are currently allocated, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_stdlib_dump_alloc_info() +{ + unsigned long i; + unsigned long c, s; + + for (i = 0, c = 0, s = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p) + { + c += 1; + s += blocks[i].s; + + printf("block[%lu] size %lu, file %s, line %d\n", + i, (unsigned long)blocks[i].s, blocks[i].file, blocks[i].line); + } + } + + if (c) + { + printf("... a total of %lu blocks, %lu bytes\n", c, s); + } + + return (0 < c) ? TRUE : FALSE; +} + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) + +/*----------------------------------------------------------------------------* + * NAME + * init_mem_debug() + * + * DESCRIPTION + * Initialisation function. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void init_mem_debug() +{ + static bool_t init_yet = FALSE; + + if (init_yet) + { + /* OK */ + } + else + { + p_memset(blocks, '\0', sizeof(blocks)); + + atexit(atexit_dump_mem); + + init_yet = TRUE; + } +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * atexit_dump_mem() + * + * DESCRIPTION + * atexit() callback function which dumps memory allocated info. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void atexit_dump_mem(void) +{ + vf_stdlib_dump_alloc_info(); +} + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + + +#endif /*defined(VFORMAT_EXCLUDE_MALLOC)*/ + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_malloc_stdlib.h b/src/vf_malloc_stdlib.h new file mode 100644 index 0000000..d765256 --- /dev/null +++ b/src/vf_malloc_stdlib.h @@ -0,0 +1,90 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_malloc.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Externs for the malloc() based memory allocator. + +MODIFICATION HISTORY + * $Log: vf_malloc_stdlib.h,v $ + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + * + *******************************************************************************/ + +#ifndef _VF_MALLOC_STDLIB_H_ +#define _VF_MALLOC_STDLIB_H_ + +#ifndef NORCSID +static const char vf_malloc_stdlib_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc_stdlib.h,v 1.1 2002/10/26 15:57:11 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_malloc(), _vf_stdlib_realloc(), _vf_stdlib_free() + * + * DESCRIPTION + * Memory allocation functions provided in terms of C runtime library + * malloc() etc. If VFORMAT_MEM_DEBUG is defined the line & file are + * passed through for ebugging purposes. + * + * RETURNS + * (various) + *----------------------------------------------------------------------------*/ + +#if defined(VFORMAT_MEM_DEBUG) + +extern void *_vf_stdlib_malloc(uint32_t s, const char *file, int line); +extern void *_vf_stdlib_realloc(void *p, uint32_t ns, const char *file, int line); +extern void _vf_stdlib_free(void *p, const char *file, int line); + +#else + +extern void *_vf_stdlib_malloc(uint32_t s); +extern void *_vf_stdlib_realloc(void *p, uint32_t ns); +extern void _vf_stdlib_free(void *p); + +#endif + +/*=============================================================================* + FIN + *============================================================================*/ + +#endif /*_VF_MALLOC_STDLIB_H_*/ diff --git a/src/vf_modified.c b/src/vf_modified.c new file mode 100644 index 0000000..427698a --- /dev/null +++ b/src/vf_modified.c @@ -0,0 +1,159 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_modified.c $ + $Revision: 1.4 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Memory allocation system for vformat parser / editor. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_modified.c,v $ + * Revision 1.4 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.3 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.2 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.1 2002/10/11 20:29:25 tilda + * Include vf_modified.c + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_modified_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_modified.c,v 1.4 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_modified.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + +/*---------------------------------------------------------------------------* + * NAME + * vf_is_modified() + * + * DESCRIPTION + * Return the status of the modified flag for the indicated object. + * + * RETURNS + * TRUE/FALSE + *---------------------------------------------------------------------------*/ + +bool_t vf_is_modified( + VF_OBJECT_T *p_object + ) +{ + bool_t ret = FALSE; + + if (p_object) + { + ret = ((VOBJECT_T *)p_object)->modified; + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * mark_property_modified() + * + * DESCRIPTION + * Mark indicated property and it's owning object as modified. If the + * recurse flag is st, then the owning object's parent object is also + * marked as modified recursively up to the top of the tree. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void mark_property_modified( + VPROP_T *p_prop, /* The property */ + bool_t recurse /* Recurse? */ + ) +{ + p_prop->modified = TRUE; + p_prop->p_parent->modified = TRUE; + + if (recurse) + { + VOBJECT_T *p_parent = p_prop->p_parent->p_parent; + + for (;p_parent;p_parent = p_parent->p_parent) + { + p_parent->modified = TRUE; + } + } +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + /*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_modified.h b/src/vf_modified.h new file mode 100644 index 0000000..f1616a4 --- /dev/null +++ b/src/vf_modified.h @@ -0,0 +1,84 @@ +/******************************************************************************* + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_modified.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Library internal access to the modification status. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_modified.h,v $ + * Revision 1.1 2002/10/11 20:22:32 tilda + * Added / repaired vf_modified.h + * + * + * 2 9/05/02 3:49p Nm2 + * Adjust memoruy allocation system for use in an embedded build. + * + * 1 7/08/02 7:24a Nm2 + * + *******************************************************************************/ + +#ifndef _VF_MODIFIED_H_ +#define _VF_MODIFIED_H_ + +#ifndef NORCSID +static const char vf_modified_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_modified.h,v 1.1 2002/10/11 20:22:32 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + +/*---------------------------------------------------------------------------* + * NAME + * mark_property_modified() + * + * DESCRIPTION + * Mark indicated property and it's owning object as modified. If the + * recurse flag is st, then the owning object's parent object is also + * marked as modified recursively up to the top of the tree. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern void mark_property_modified( + VPROP_T *p_prop, /* The property */ + bool_t recurse /* Recurse? */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_MODIFIED_H_*/ diff --git a/src/vf_parser.c b/src/vf_parser.c new file mode 100644 index 0000000..bf7b789 --- /dev/null +++ b/src/vf_parser.c @@ -0,0 +1,1182 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_parser.c $ + $Revision: 1.22 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Parser for text stream in vobject format. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_parser.c,v $ + * Revision 1.22 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.21 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.20 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.19 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.18 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.17 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.16 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.15 2002/10/08 21:25:28 tilda + * Assignment of parent property. + * + * Revision 1.14 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.13 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.12 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.11 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.10 2001/10/24 05:32:19 tilda + * BASE64 bugfixes - first part + * + * Revision 1.9 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_parser_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_parser.c,v 1.22 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *===========================================================================*/ + +#include <common/types.h> + +/*============================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *===========================================================================*/ + +/* + * Significant characters. + */ +#define PERIOD '.' +#define COLON ':' +#define SEMICOLON ';' +#define LINEFEED '\n' +#define CRETURN '\r' +#define TAB '\t' +#define BACKSLASH '\\' +#define SPACE ' ' +#define EQUALS '=' +#define PERIOD '.' + +/* + * dec hex oct char + * 10 0x0A 012 LF NL, line feed, new line, \n + * 13 0x0D 015 CR carriage return, \r + * + * => <CR><LF> = 0x0D 0x0A + */ + +/* + * States associated with propname:propvalue parsing. + */ +#define _VF_STATE_PROPNAME (1) /* reading name (including groupings) */ +#define _VF_STATE_PROPNAMEESCAPE (2) /* escaped semicolon in name */ +#define _VF_STATE_RFC822VALUE (3) /* basic */ +#define _VF_STATE_RFC822VALUEFOLD (4) /* waiting for line fold (simple fields) */ +#define _VF_STATE_QPIDLE (5) /* Non escaped position in QP */ +#define _VF_STATE_QPIDLENL (6) /* Non escaped position in QP */ +#define _VF_STATE_QPEQUALSC1 (7) /* After = in QP */ +#define _VF_STATE_QPEQUALSC2 (8) /* After =X in QP */ +#define _VF_STATE_BASE64 (9) /* Reading BASE64 */ + +#define ISCRORNL(c) ((CRETURN == (c)) || (LINEFEED == (c))) + +/*============================================================================* + Private Data Types + *===========================================================================*/ + +/*----------------------------------------------------------------------------* + * PURPOSE + * Maintains state variables etc. for current VOBJECT_T parsing. + *----------------------------------------------------------------------------*/ + +typedef struct +{ + int state; /* Main state variable */ + char qpchar; /* Workspace for QuotedPrintable decoder */ + char *p_b64buf; /* Workspace for BASE64 decoder */ + VOBJECT_T **pp_root_object; /* Pointer to the root */ + VOBJECT_T *p_object; /* Current position in tree */ + VPROP_T prop; /* Current property, copied into tree on completion */ +} +VPARSE_T; + +/*============================================================================* + Private Function Prototypes + *===========================================================================*/ + +static bool_t append_value_to_object( + VPROP_T **pp_prop, /* Pointer to the new property */ + VPARSE_T *p_parse /* The property we're naming */ + ); + +static bool_t handle_base64_chars( + VPARSE_T *p_parse, /* The property value we're adding to */ + const char *p_chars, /* Pointer to characters to add */ + int numchars /* Number of characters */ + ); + +static vf_encoding_t deduce_encoding( + VSTRARRAY_T *p_propname /* Property name */ + ); + +static uint8_t base64_to_char( + char c /* Character to convert */ + ); + +static bool_t is_hex_digit( + char *p_nibble, /* Output nibble value */ + char c /* Character read from file */ + ); + +static bool_t handle_value_complete( + VPARSE_T *p_parse /* Current parse state info */ + ); + +static bool_t alloc_next_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ); + +static bool_t alloc_sub_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ); + +static bool_t alloc_object( + VOBJECT_T **pp_new, /* Pointer to output pointer */ + VOBJECT_T *p_parent, /* Parent of new node */ + char *p_type, /* Type of new node */ + VPARSE_T *p_parse /* Current parse info */ + ); + +static bool_t append_group_name( + VPROP_T *p_prop /* Property we're updating */ + ); + + +/*============================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *===========================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_init() + * + * DESCRIPTION + * Initialise a parsing instance. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_init( + VF_PARSER_T **pp_parser, /* The parser */ + VF_OBJECT_T **pp_object /* The object we're parsing into */ + ) +{ + bool_t ret = FALSE; + + if (pp_parser && pp_object) + { + VPARSE_T *p_parse = (VPARSE_T *)vf_malloc(sizeof(VPARSE_T)); + + if (p_parse) + { + p_memset(p_parse, '\0', sizeof(VPARSE_T)); + + p_parse->state = _VF_STATE_PROPNAME; + p_parse->p_object = NULL; + p_parse->pp_root_object = (VOBJECT_T **)pp_object; + + *pp_parser = (VF_PARSER_T *)p_parse; + + *pp_object = NULL; + + ret = TRUE; + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_text() + * + * DESCRIPTION + * Parse indicated text into the object associated with the VPARSE_T. + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_text( + VF_PARSER_T *p_parser, /* The parser */ + char *p_chars, /* New characters to parse into object */ + int numchars /* Number of new characters */ + ) +{ + int i; + bool_t ok; + VPARSE_T *p_parse = (VPARSE_T *)p_parser; + + /* + * Check pointer. + */ + if (!p_parse) + { + return FALSE; + } + + /* + * Push each character through the state machine. + */ + for (i = 0, ok = TRUE;ok && (i < numchars);i++) + { + char c = p_chars[i]; + + switch (p_parse->state) + { + case _VF_STATE_RFC822VALUEFOLD: + { + if (ISCRORNL(c)) + { + /* Ignore */ + } + else + if (SPACE == c) + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + + p_parse->state = _VF_STATE_RFC822VALUE; + } + else + { + ok = handle_value_complete(p_parse); + + p_parse->state = _VF_STATE_PROPNAME; + } + } + if (_VF_STATE_PROPNAME == p_parse->state) + { + /* Fall through */ + } + else + { + break; + } + + /* Fall through */ + + + case _VF_STATE_PROPNAME: + { + if (COLON == c) + { + p_parse->prop.value.encoding = deduce_encoding(&p_parse->prop.name); + + switch (p_parse->prop.value.encoding) + { + case VF_ENC_7BIT: + p_parse->state = _VF_STATE_RFC822VALUE; + break; + + case VF_ENC_BASE64: + p_parse->state = _VF_STATE_BASE64; + break; + + case VF_ENC_QUOTEDPRINTABLE: + p_parse->state = _VF_STATE_QPIDLE; + break; + + default: + ok = FALSE; + break; + } + } + else + if (BACKSLASH == c) + { + p_parse->state = _VF_STATE_PROPNAMEESCAPE; + } + else + if (ISCRORNL(c)) + { + /* ignore */ + + free_string_array_contents(&p_parse->prop.name); + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&p_parse->prop.name, ""); + } + else + if (PERIOD == c) + { + ok = append_group_name(&p_parse->prop); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.name), NULL, &c, 1); + } + } + break; + + case _VF_STATE_PROPNAMEESCAPE: + { + if (SEMICOLON == c) + { + ok = append_to_curr_string(&(p_parse->prop.name), NULL, &c, 1); + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_RFC822VALUE: + { + if (p_parse->prop.value.v.s.pp_strings) + { + /* Already allocated */ + } + else + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + + if (ISCRORNL(c)) + { + p_parse->state = _VF_STATE_RFC822VALUEFOLD; + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + } + } + break; + + case _VF_STATE_QPIDLENL: + { + if (ISCRORNL(c)) + { + break; + } + else + { + p_parse->state = _VF_STATE_QPIDLE; + } + } + + case _VF_STATE_QPIDLE: + { + if (p_parse->prop.value.v.s.pp_strings) + { + /* Already allocated */ + } + else + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + + if (EQUALS == c) + { + p_parse->qpchar = 0x00; + p_parse->state = _VF_STATE_QPEQUALSC1; + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + else + if (ISCRORNL(c)) + { + ok = handle_value_complete(p_parse); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + } + } + break; + + case _VF_STATE_QPEQUALSC1: + { + uint8_t nibble; + + if (ISCRORNL(c)) + { + p_parse->state = _VF_STATE_QPIDLENL; + } + else + if (is_hex_digit(&nibble, c)) + { + (p_parse->qpchar) <<= 4; + (p_parse->qpchar) |= nibble; + + p_parse->state = _VF_STATE_QPEQUALSC2; + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_QPEQUALSC2: + { + uint8_t nibble; + + if (is_hex_digit(&nibble, c)) + { + (p_parse->qpchar) <<= 4; + (p_parse->qpchar) |= nibble; + + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &(p_parse->qpchar), 1); + + p_parse->state = _VF_STATE_QPIDLE; + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_BASE64: + { + /* + * The cr/nl stuff associated with line ends & termination of BASE64 encoding + * seems to be particularly problematic. Searching and reading vCards from the + * internet shows that all sorts of wierd things are out there in use! In the + * interests of interoperability we look for the next value as an indication of + * the end of the object. We build up each line and if it's still in BASE64 + * format append the decoded data. Otherwise we use the parser recursively to + * decode the buffered text, which is probably something like "NEXT-VALUE:" + */ + + if (ISCRORNL(c)) + { + if (p_parse->p_b64buf) + { + ok = handle_base64_chars(p_parse, p_parse->p_b64buf, p_strlen(p_parse->p_b64buf)); + + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + } + else + { + ok = append_to_pointer(&(p_parse->p_b64buf), NULL, &c, 1); + + if ((COLON == c) || (SEMICOLON == c)) + { + ok = handle_value_complete(p_parse); + + ok = vf_parse_text(p_parser, p_parse->p_b64buf, p_strlen(p_parse->p_b64buf)); + + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + } + } + break; + } + } + + if (ok) + { + /* no need to panic */ + } + else + { + vf_delete_object((VF_OBJECT_T *)*(p_parse->pp_root_object), TRUE); + *(p_parse->pp_root_object) = NULL; + p_parse->p_object = NULL; + + if (p_parse->p_b64buf) + { + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + + delete_prop_contents((VF_PROP_T *)&p_parse->prop, TRUE); + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_end() + * + * DESCRIPTION + * Ensure parse completion. + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_end( + VF_PARSER_T *p_parser /* The parser */ + ) +{ + bool_t ret = FALSE; + VPARSE_T *p_parse = (VPARSE_T *)p_parser; + + /* + * Check pointer. + */ + if (p_parse) + { + ret = handle_value_complete(p_parse); + + vf_free(p_parse); + } + + return ret; +} + + + + +/*============================================================================* + Private Functions + *===========================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * append_group_name() + * + * DESCRIPTION + * After reading a ".", we transfer the segment of name we've read (which + * must be the first string <G>) into the group name. Keep the group name + * in one string of "." tokens for simplicity, so we may end up with a + * group called "X-PHONE-BOOK.ENTRY.1" etc. + * + * RETURNS + * TRUE <=> allocation OK. + *---------------------------------------------------------------------------*/ + +bool_t append_group_name( + VPROP_T *p_prop + ) +{ + bool_t ok = TRUE; + + if (p_prop->p_group) + { + ok &= append_to_pointer(&p_prop->p_group, NULL, ".", 1); + } + + if (ok) + { + const char *p_string = p_prop->name.pp_strings[0]; + + ok &= append_to_pointer(&p_prop->p_group, NULL, p_string, p_strlen(p_string)); + + if (ok) + { + vf_free(p_prop->name.pp_strings[0]); + p_prop->name.pp_strings[0] = NULL; + } + } + + return ok; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * handle_value_complete() + * + * DESCRIPTION + * Called when a complete value is parsed. + * + * RETURNS + * (none). + *---------------------------------------------------------------------------*/ + +bool_t handle_value_complete( + VPARSE_T *p_parse /* Current parse state info */ + ) +{ + bool_t ret = TRUE; + VOBJECT_T *p_object; + + /* + * If we've got no object open we ignore values until we read a BEGIN at which point + * we create a vformat object and start to parse properties into it. If we subsequently + * read a BEGIN we add a property & parse the next vobject into that. Each time we read + * an END we pop the pp_object pointer back up to the owner of the object we're parsing + * into. There should be an easier way of doing this <G> ... + */ + + p_object = p_parse->p_object; + + if (p_object) + { + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_BEGIN, TRUE)) + { + char *p_type; + + p_type = p_parse->prop.value.v.s.pp_strings[0]; + p_parse->prop.value.v.s.pp_strings[0] = NULL; + + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + + p_parse->prop.value.encoding = VF_ENC_VOBJECT; + + ret = add_string_to_array(&(p_parse->prop.name), p_type) && + alloc_sub_object(p_parse, p_type); + } + else + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_END, TRUE)) + { + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + + p_parse->p_object = p_parse->p_object->p_parent; + } + else + { + ret = append_value_to_object(NULL, p_parse); + } + } + else + { + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_BEGIN, TRUE)) + { + char *p_type; + + p_type = p_parse->prop.value.v.s.pp_strings[0]; + p_parse->prop.value.v.s.pp_strings[0] = NULL; + + ret = alloc_next_object(p_parse, p_type); + } + + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + } + + p_parse->state = _VF_STATE_PROPNAME; + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_next_object() + * + * DESCRIPTION + * Allocate the "next" object, ie. annother vformat tagged to the p_next + * pointer to the current one. + * + * RETURNS + * TRUE iff memory allocated OK, FALSE else OK. + *---------------------------------------------------------------------------*/ + +bool_t alloc_next_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ) +{ + bool_t ok = TRUE; + VOBJECT_T *p_parent = p_parse->p_object; + VOBJECT_T *p_new = NULL; + + ok = alloc_object(&p_new, p_parent ? p_parent->p_parent : NULL, p_type, p_parse); + + if (ok) + { + if (*p_parse->pp_root_object) + { + /* root object already set */ + + if (p_new->p_parent) + { + /* Owned by property */ + } + else + { + /* Need to tag to end of top list */ + + VOBJECT_T **pp_tmp = p_parse->pp_root_object; + + while (*pp_tmp) + { + pp_tmp = &((*pp_tmp)->p_next); + } + + *pp_tmp = p_new; + } + } + else + { + *p_parse->pp_root_object = p_new; + } + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_sub_object() + * + * DESCRIPTION + * Allocate "sub" object, ie. annother vformat tagged to the p_object + * pointer of a VPROP_T allocated to contain it. + * + * RETURNS + * TRUE iff memory allocated OK, FALSE else OK. + *---------------------------------------------------------------------------*/ + +bool_t alloc_sub_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ) +{ + bool_t ok = FALSE; + VOBJECT_T *p_parent = p_parse->p_object; + + if (p_parent) + { + VPROP_T *p_tmp; + + ok = append_value_to_object(&p_tmp, p_parse); + + if (ok && p_tmp) + { + ok = alloc_object(&p_tmp->value.v.o.p_object, p_parent, p_type, p_parse); + } + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_object() + * + * DESCRIPTION + * Allocate & initialise a new VOBJECT_T. The new element od made the + * current parse target (ie. new properties will be added to it). + * + * RETURNS + * TRUE <=> allocation went OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t alloc_object( + VOBJECT_T **pp_new, /* Pointer to output pointer */ + VOBJECT_T *p_parent, /* Parent of new node */ + char *p_type, /* Type of new node */ + VPARSE_T *p_parse /* Current parse info */ + ) +{ + bool_t ok = TRUE; + VOBJECT_T *p_new; + + p_new = (VOBJECT_T *)vf_malloc(sizeof(VOBJECT_T)); + + if (p_new) + { + p_memset(p_new, '\0', sizeof(VOBJECT_T)); + + p_new->p_parent = p_parent; + p_new->p_type = p_type; + + p_parse->p_object = p_new; + + *pp_new = p_new; + } + else + { + ok = FALSE; + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * handle_base64_chars() + * + * DESCRIPTION + * Handle BASE64 decoding. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t handle_base64_chars( + VPARSE_T *p_parse, /* The property value we're adding to */ + const char *p_chars, /* Pointer to characters to add */ + int numchars /* Number of characters */ + ) +{ + bool_t ok = TRUE; + + /* + * Skip spaces. + */ + while ((0 < numchars) && (SPACE == p_chars[0])) + { + numchars--; + p_chars++; + } + + /* + * Convert groups of 4 characters to byte triplets & append the bytes + * to the binary data. + */ + if (0 < numchars) + { + int i, j, len, num, left; + const char *p_quad; + + len = numchars; + num = len / 4; + left = len % 4; + + for (i = 0, p_quad = p_chars;(i < num);i++, p_quad += 4) + { + uint32_t b; + char bytes[3]; + uint8_t bits; + + for (j = 0, b = 0, bits = 0;(j < 4);j++) + { + b = (b << 6) | base64_to_char(p_quad[j]); + + if (EQUALS != p_quad[j]) + { + bits += 6; + } + } + + for (j = 0;(j < 3);j++) + { + bytes[2 - j] = (unsigned char)(b & 0xFF); + + b >>= 8; + } + + ok = append_to_pointer(&(p_parse->prop.value.v.b.p_buffer), &(p_parse->prop.value.v.b.n_bufsize), bytes, bits / 8); + } + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_value_to_object() + * + * DESCRIPTION + * Append characters to the name half of a VOBJECT_T. The VOBJECT is + * allocated if not already present. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t append_value_to_object( + VPROP_T **pp_prop, /* Pointer to the new property */ + VPARSE_T *p_parse /* The property we're naming */ + ) +{ + bool_t ok = FALSE; + + VPROP_T **pp_tmp; + VPROP_T *p_prop; + + pp_tmp = &(p_parse->p_object->p_props); + + while (*pp_tmp) + { + pp_tmp = &((*pp_tmp)->p_next); + } + + *pp_tmp = p_prop = (VPROP_T *)vf_malloc(sizeof(VPROP_T)); + + if (pp_prop) + { + *pp_prop = p_prop; + } + + if (p_prop) + { + p_memset(p_prop, '\0', sizeof(VPROP_T)); + + *p_prop = p_parse->prop; + + p_memset(&(p_parse->prop), '\0', sizeof(VPROP_T)); + + p_prop->p_parent = p_parse->p_object; + + ok = TRUE; + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * deduce_encoding() + * + * DESCRIPTION + * Check property name for encoding tags. If none present, return the + * default encoding. + * + * RETURNS + * vf_encoding_t. + *---------------------------------------------------------------------------*/ + +vf_encoding_t deduce_encoding( + VSTRARRAY_T *p_propname /* Property name */ + ) +{ + vf_encoding_t ret = VF_ENC_7BIT; + + if (string_array_contains_string(p_propname, NULL, -1, VFP_QUOTEDPRINTABLE, FALSE)) + { + ret = VF_ENC_QUOTEDPRINTABLE; + } + else + if (string_array_contains_string(p_propname, NULL, -1, VFP_BASE64, FALSE)) + { + ret = VF_ENC_BASE64; + } + else + if (string_array_contains_string(p_propname, NULL, -1, VFP_8BIT, FALSE)) + { + ret = VF_ENC_8BIT; + } + + return ret; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * is_hex_digit() + * + * DESCRIPTION + * + * + * RETURNS + * TRUE <=> valid HEX digit read. + *---------------------------------------------------------------------------*/ + +bool_t is_hex_digit( + char *p_nibble, /* Output nibble value */ + char c /* Character read from file */ + ) +{ + bool_t ret = TRUE; + + if (('A' <= c) && (c <= 'F')) + { + *p_nibble = c - 'A' + 10; + } + else + if (('a' <= c) && (c <= 'f')) + { + *p_nibble = c - 'a' + 10; + } + else + if (('0' <= c) && (c <= '9')) + { + *p_nibble = c - '0'; + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * base64_to_char() + * + * DESCRIPTION + * Convert base 64 char to byte. + * + * RETURNS + * Number corresponding to char. + *---------------------------------------------------------------------------*/ + +uint8_t base64_to_char(char c) +{ + if (('A' <= c) && (c <= 'Z')) + return c - 'A'; + + if (('a' <= c) && (c <= 'z')) + return c - 'a' + 26; + + if (('0' <= c) && (c <= '9')) + return c - '0' + 52; + + if ('+' == c) + return 62; + + if ('/' == c) + return 63; + + return 0x00; +} + + +/*============================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_reader.c b/src/vf_reader.c new file mode 100644 index 0000000..667279f --- /dev/null +++ b/src/vf_reader.c @@ -0,0 +1,277 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_reader.c $ + $Revision: 1.18 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + Code for reading vformat files from disk. Delegates the real responsibility + to vf_parser for actually converting chunks of text into the memory data + structure. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_reader.c,v $ + * Revision 1.18 2002/11/15 09:20:59 tilda + * IID638823 - Don't include unistd.h unless required. + * + * Revision 1.17 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.16 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.15 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.14 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.13 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.12 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.11 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.10 2001/10/24 05:32:19 tilda + * BASE64 bugfixes - first part + * + * Revision 1.9 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:02 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:55 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_reader_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_reader.c,v 1.18 2002/11/15 09:20:59 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include <common/types.h> + +#include <stdio.h> +#include <sys/stat.h> + +#if defined(HAS_UNISTD_H) +#include <unistd.h> +#endif + +#if defined(WIN) || defined(WIN32) +#include <io.h> +#endif + + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include <vformat/vf_iface.h> + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_malloc.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define PARSEBUFSIZE (1024) + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + +/*----------------------------------------------------------------------------* + * NAME + * vf_read_file() + * + * DESCRIPTION + * Reads indicated VOBJECT_T file. + * + * RETURNS + * TRUE <=> read OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_read_file( + VF_OBJECT_T **pp_object, + const char *p_name + ) +{ + bool_t ret = FALSE; + + if (pp_object) + { + FILE *fp; + + fp = fopen(p_name, "rb"); + + if (fp) + { + char buffer[PARSEBUFSIZE]; + int charsread; + VF_PARSER_T *p_parser; + + if (vf_parse_init(&p_parser, pp_object)) + { + do + { + charsread = read(fileno(fp), buffer, sizeof(buffer)); + + if (0 < charsread) + { + ret = vf_parse_text(p_parser, buffer, charsread); + } + } + while (ret && (0 < charsread)) + ; + + if (!vf_parse_end(p_parser)) + { + ret = FALSE; + } + } + + if (0 == fclose(fp)) + { + /* OK */ + } + else + { + ret = FALSE; + } + } + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_property_from_file() + * + * DESCRIPTION + * Loads the indicated file into memory and sets the indicated property. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +bool_t vf_set_property_from_file( + VF_PROP_T *p_prop, /* The property */ + vf_encoding_t encoding, /* Encoding to use */ + const char *p_filename /* Source filename */ + ) +{ + bool_t ret = FALSE; + struct stat buf; + + if (0 == stat(p_filename, &buf)) + { + uint8_t *p_data = vf_malloc(buf.st_size); + + if (p_data) + { + FILE *fp = fopen(p_filename, "rb"); + + if (fp) + { + if ((int)buf.st_size == read(fileno(fp), p_data, buf.st_size)) + { + ret = TRUE; + } + + if (0 == fclose(fp)) + { + /* */ + } + else + { + ret = FALSE; + } + + if (ret) + { + ret &= vf_set_prop_value(p_prop, p_data, buf.st_size, encoding, TRUE); + } + } + + vf_free(p_data); + } + } + + return ret; +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_search.c b/src/vf_search.c new file mode 100644 index 0000000..71be484 --- /dev/null +++ b/src/vf_search.c @@ -0,0 +1,457 @@ +/**************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_access.c $ + $Revision: 1.11 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Basic searching functions for the vformat library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_search.c,v $ + * Revision 1.11 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.10 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.9 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.8 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.7 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.6 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.5 2001/11/18 21:46:59 tilda + * Remove redundant code. + * + * Revision 1.4 2001/11/16 22:34:50 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.3 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_search_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_search.c,v 1.11 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <common/types.h> + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +/* + * Maximum supported search tags. + */ +#define MAXNUMTAGS (10) + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property() + * + * DESCRIPTION + * Basic searching function locating elements of the VOBJECT by qualified + * name. The function is a varargs function (like sprintf) and the list + * of arguments must be NULL terminated (hence the appearance of the + * p_qualifier argument in the arglist). Valid calls might be: + * + * vf_get_property(&p_out, p_object, FALSE, NULL, "N", NULL); + * vf_get_property(&p_out, p_object, FALSE, NULL, "TEL", "WORK", NULL); + * vf_get_property(&p_out, p_object, FALSE, "ME", "TEL", "WORK", NULL); + * vf_get_property(&p_out, p_object, FALSE, "ME", "*", NULL); + * + * A pointer to the first property matching the search criteria is returned + * the pp_prop argument. The search actually locates all such matches and + * pointer to subsequent entries (if there are >1) may be found by calling + * the vf_get_next_property() function. + * + * Qualifying tags (ie. not the name) may occur in any order + * + * Note that the VF_PROP_T returned vi pp_prop is an opaque type and the + * various accessor functions must be used to get to the data. + * + * RETURNS + * TRUE iff found/added successfully. ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_property( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to add to */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + ... /* Subequent qualifiers */ + ) +{ + bool_t ret = FALSE; + va_list args; + + va_start(args, p_qualifier); + + ret = vf_get_property_ex(pp_prop, p_object, ops, p_group, p_name, p_qualifier, args); + + va_end(args); + + return ret; +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property_ex() + * + * DESCRIPTION + * The grunt behind vf_get_property(). Manages the search as described + * vf_get_property() but takes the list of arguments as a va_list. + * + * RETURNS + * TRUE iff found / appended OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_property_ex( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to search */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + va_list args /* Argument list */ + ) +{ + bool_t ret = FALSE; + char **pp_tags = NULL; + + if (!p_name || !p_object) + return ret; + + if (pp_prop) + { + *pp_prop = NULL; + } + + pp_tags = (char **)vf_malloc(MAXNUMTAGS * sizeof(char *)); + + if (pp_tags) + { + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + VPROP_T *p_props = p_obj->p_props; + int i; + + VPROP_T **pp_lastprop = &(p_obj->p_props); + VPROP_T **pp_next_srch = NULL; + + p_memset(pp_tags, '\0', MAXNUMTAGS * sizeof(char *)); + + pp_tags[0] = (char *)p_name; + + /* + * The name is the first tag. We insist on there being at least one qualifier in the + * argument list to make sure callers terminate the list. Subsequent arguments are + * optional, but will be ignored if the (first) qualifier is NULL. + */ + if (p_qualifier) + { + pp_tags[1] = (char *)p_qualifier; + + for (i = 2;i < MAXNUMTAGS;i++) + { + char *p_tag = va_arg(args, char *); + + if (p_tag) + { + pp_tags[i] = p_tag; + } + else + { + break; + } + } + } + + if (ops & VFGP_FIND) + { + /* + * Skip down the list or properties. I'm assuming that we only want to search the + * current object for properties not the current object AND any contained objects. + * Such a search sounds a bit application specific, ie. the caller would be looking + * for a particular structure of things. Each element that is found is stitched + * into the emerging list. + */ + for (;NULL != p_props;p_props = p_props->p_next) + { + bool_t found = TRUE; + + /* + * Check the name & qualifiers. + */ + for (i = 0;found && (i < MAXNUMTAGS) && pp_tags[i];i++) + { + if (0 != p_strcmp(VFP_ANY, pp_tags[i])) + found &= string_array_contains_string(&p_props->name, NULL, -1, pp_tags[i], TRUE); + } + if (p_group && found) + { + found = FALSE; + + if (p_props->p_group) + { + if (0 == p_stricmp(p_props->p_group, p_group)) + { + found = TRUE; + } + } + else + { + /* Search group specified & property doesn't have a group => not required */ + } + } + + if (found) + { + if (pp_prop) + { + if (!*pp_prop) + { + pp_next_srch = &(p_props->p_next_srch); + p_props->p_next_srch = NULL; + + *pp_prop = (VF_PROP_T *)p_props; + } + else + { + *pp_next_srch = p_props; + + pp_next_srch = &(p_props->p_next_srch); + p_props->p_next_srch = NULL; + } + } + + ret = TRUE; + } + + if (p_props->p_next) + { + pp_lastprop = &(p_props->p_next); + } + } + } + + if (!ret && (ops & VFGP_APPEND)) + { + VPROP_T *p_new = (VPROP_T *)vf_malloc(sizeof(VPROP_T)); + + if (p_new) + { + ret = TRUE; + + p_memset(p_new, '\0', sizeof(VPROP_T)); + + p_new->p_parent = p_obj; + + for (i = 0;ret && (i < MAXNUMTAGS) && pp_tags[i];i++) + { + ret = add_string_to_array(&p_new->name, pp_tags[i]); + } + + if (ret) + { + /* All OK */ + + p_new->value.encoding = VF_ENC_7BIT; + } + else + { + free_string_array_contents(&p_new->name); + + vf_free(p_new); + p_new = NULL; + } + } + + if (p_new) + { + if (pp_prop) + { + *pp_prop = (VF_PROP_T *)p_new; + } + + p_new->p_next = *pp_lastprop; + *pp_lastprop = p_new; + + ret = TRUE; + } + } + + vf_free(pp_tags); + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_property() + * + * DESCRIPTION + * Find the next property given the current search critera. + * + * RETURNS + * TRUE iff found, FALSE else. *pp_prop points to the next property. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_next_property( + VF_PROP_T **pp_prop /* Output pointer */ + ) +{ + bool_t ret = FALSE; + + if (pp_prop) + { + VPROP_T **pp_vprop = (VPROP_T **)pp_prop; + + if (*pp_vprop) + { + *pp_prop = (VF_PROP_T *)((*pp_vprop)->p_next_srch); + + if (*pp_prop) + { + ret = TRUE; + } + } + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_object() + * + * DESCRIPTION + * Find "next" vobject. + * + * RETURNS + * TRUE iff found next object. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_next_object( + VF_OBJECT_T **pp_object + ) +{ + bool_t ret = FALSE; + + if (pp_object) + { + if (*pp_object) + { + *pp_object = (VF_OBJECT_T *)(((VOBJECT_T *)(*pp_object))->p_next); + + if (*pp_object) + { + ret = TRUE; + } + } + } + + return ret; +} + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ +/* None */ + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_string_arrays.c b/src/vf_string_arrays.c new file mode 100644 index 0000000..eee27f4 --- /dev/null +++ b/src/vf_string_arrays.c @@ -0,0 +1,435 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_access.c $ + $Revision: 1.4 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Utility functions handling string arrays - the VSTRARRAY_T type. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_string_arrays.c,v $ + * Revision 1.4 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.3 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.2 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_string_arrays_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_string_arrays.c,v 1.4 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include <common/types.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * string_array_contains_string() + * + * DESCRIPTION + * Checks the strings in the indicated array to see if it contains a + * particulr value. Can check a particular index or the whole array. + * Can perform an exact match or check wether one of the strings simply + * contains the value. + * + * RETURNS + * TRUE <=> includes indicated value, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t string_array_contains_string( + VSTRARRAY_T *p_strarray, /* String array */ + char **pp_string_found, /* String found */ + uint32_t index, /* Which entry, (-1) => any */ + const char *p_string, /* The string we're looking for */ + bool_t exact /* Exact or partial match */ + ) +{ + bool_t ret = FALSE; + uint32_t i; + uint32_t s, e; + + if (index == (-1)) + { + s = 0; + e = p_strarray->n_strings; + } + else + { + s = index; + e = index + 1; + } + + for (i = s;!ret && (i < e);i++) + { + if ((i < p_strarray->n_strings) && p_strarray->pp_strings[i]) + { + if (exact) + { + if (0 == p_stricmp(p_strarray->pp_strings[i], p_string)) + ret = TRUE; + } + else + { + if (p_strstr(p_strarray->pp_strings[i], p_string)) + ret = TRUE; + } + } + + if (ret && pp_string_found) + { + *pp_string_found = p_strarray->pp_strings[i]; + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * add_string_to_array() + * + * DESCRIPTION + * Append string to indicated array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t add_string_to_array( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string /* String to add */ + ) +{ + char **pp_new; + bool_t ret = FALSE; + + pp_new = vf_realloc(p_strarray->pp_strings, sizeof(char *) * (1 + p_strarray->n_strings)); + + if (pp_new) + { + if (p_string) + { + uint32_t l; + char *p_strcopy; + + l = p_strlen(p_string); + + p_strcopy = vf_malloc(1 + l); + + if (p_strcopy) + { + p_strcpy(p_strcopy, p_string); + + pp_new[p_strarray->n_strings] = p_strcopy; + + ret = TRUE; + } + else + { + vf_free(pp_new); + } + } + else + { + pp_new[p_strarray->n_strings] = NULL; + + ret = TRUE; + } + + if (ret) + { + p_strarray->n_strings += 1; + p_strarray->pp_strings = pp_new; + } + } + + return ret; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * free_string_array_contents() + * + * DESCRIPTION + * Delete contents of a string array. The structure itself is not free()d. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void free_string_array_contents( + VSTRARRAY_T *p_strarray /* String array */ + ) +{ + if (p_strarray && p_strarray->pp_strings) + { + uint32_t i; + + for (i = 0;i < p_strarray->n_strings;i++) + { + if (p_strarray->pp_strings[i]) + { + vf_free(p_strarray->pp_strings[i]); + p_strarray->pp_strings[i] = NULL; + } + } + + vf_free(p_strarray->pp_strings); + p_strarray->pp_strings = NULL; + + p_strarray->n_strings = 0; + } +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_curr_string() + * + * DESCRIPTION + * Append characters to the current string in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t append_to_curr_string( + VSTRARRAY_T *p_strarray, /* String array */ + uint32_t *p_length, /* Pointer to length, NULL if zero terminated */ + const char *p_chars, /* Characters to append */ + uint32_t numchars /* Number of characters */ + ) +{ + bool_t ret = TRUE; + + if (p_strarray && !p_strarray->pp_strings) + { + ret = add_string_to_array(p_strarray, ""); + } + + if (ret) + { + ret = append_to_pointer(&(p_strarray->pp_strings[p_strarray->n_strings - 1]), p_length, p_chars, numchars); + } + + return ret; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_pointer() + * + * DESCRIPTION + * Append characters to indicated pointer. Handles both NULL terminated + * strings (for simple 7-bit values) and buffer/length pairs. Passing + * the p_length field indicates that we're building up binary data. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t append_to_pointer( + char **pp_string, /* String we're appending to */ + uint32_t *p_length, /* Pointer to length, NULL if ZT */ + const char *p_chars, /* Chars we're appending */ + int numchars /* Number of chars we're appending */ + ) +{ + bool_t ok = FALSE; + + if (pp_string) + { + int newlen, currlen; + char *p_new; + + newlen = numchars; + + if (*pp_string) + { + currlen = p_length ? *p_length : p_strlen(*pp_string); + + newlen += currlen; + } + else + { + currlen = 0; + } + + p_new = vf_realloc(*pp_string, newlen + (p_length ? 0 : 1)); + + if (p_new) + { + p_memcpy(p_new + currlen, p_chars, numchars); + + if (p_length) + { + *p_length = newlen; + } + else + { + p_new[newlen] = '\0'; + } + + *pp_string = p_new; + ok = TRUE; + } + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * set_string_array_entry() + * + * DESCRIPTION + * Set indicated entry in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t set_string_array_entry( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string, /* String to insert */ + uint32_t n_string /* Insertion point */ + ) +{ + bool_t ret = FALSE; + + if (n_string < p_strarray->n_strings) + { + if (p_strarray->pp_strings[n_string]) + { + vf_free(p_strarray->pp_strings[n_string]); + p_strarray->pp_strings[n_string] = NULL; + } + + if (p_string) + { + uint32_t len = p_strlen(p_string); + + p_strarray->pp_strings[n_string] = vf_malloc(1 + len); + + if (p_strarray->pp_strings[n_string]) + { + p_strcpy(p_strarray->pp_strings[n_string], p_string); + + ret = TRUE; + } + } + else + { + /* NULL = "delete" */ + + ret = TRUE; + } + } + + return ret; +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_string_arrays.h b/src/vf_string_arrays.h new file mode 100644 index 0000000..252da03 --- /dev/null +++ b/src/vf_string_arrays.h @@ -0,0 +1,177 @@ +/******************************************************************************* + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_internals.h $ + $Revision: 1.2 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Utility functions handling string arrays - the VSTRARRAY_T type. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_string_arrays.h,v $ + * Revision 1.2 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#ifndef _VF_STRING_ARRAYS_H_ +#define _VF_STRING_ARRAYS_H_ + +#ifndef NORCSID +static const char vf_string_arrays_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_string_arrays.h,v 1.2 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * string_array_contains_string() + * + * DESCRIPTION + * Checks the strings in the indicated array to see if it contains a + * particulr value. Can check a particular index or the whole array. + * Can perform an exact match or check wether one of the strings simply + * contains the value. + * + * RETURNS + * TRUE <=> includes indicated value, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t string_array_contains_string( + VSTRARRAY_T *p_strarray, /* String array */ + char **pp_string_found, /* String found */ + uint32_t index, /* Which entry, (-1) => any */ + const char *p_string, /* The string we're looking for */ + bool_t exact /* Exact or partial match */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * add_string_to_array() + * + * DESCRIPTION + * Append string to indicated array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t add_string_to_array( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string /* String to add */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * free_string_array_contents() + * + * DESCRIPTION + * Delete contents of a string array. The structure itself is not free()d. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void free_string_array_contents( + VSTRARRAY_T *p_strarray /* String array */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_curr_string() + * + * DESCRIPTION + * Append characters to the current string in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t append_to_curr_string( + VSTRARRAY_T *p_strarray, /* String array */ + uint32_t *p_length, /* Pointer to length, NULL if zero terminated */ + const char *p_chars, /* Characters to append */ + uint32_t numchars /* Number of characters */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_pointer() + * + * DESCRIPTION + * Append characters to indicated pointer. Handles both NULL terminated + * strings (for simple 7-bit values) and buffer/length pairs. Passing + * the p_length field indicates that we're building up binary data. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t append_to_pointer( + char **pp_string, /* String we're appending to */ + uint32_t *p_length, /* Pointer to length, NULL if ZT */ + const char *p_chars, /* Chars we're appending */ + int numchars /* Number of chars we're appending */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * set_string_array_entry() + * + * DESCRIPTION + * Set indicated entry in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t set_string_array_entry( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string, /* String to insert */ + uint32_t n_string /* Insertion point */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_STRING_ARRAYS_H_*/ diff --git a/src/vf_strings.c b/src/vf_strings.c new file mode 100644 index 0000000..204a188 --- /dev/null +++ b/src/vf_strings.c @@ -0,0 +1,472 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.9 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + String handling functions. The library uses the p_ functions (where hopefully + the 'p' stands for 'portable') and they are provided here in terms of C runtime + functions or implemented explicitly. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_strings.c,v $ + * Revision 1.9 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.8 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.7 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.6 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.5 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.4 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.3 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.2 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.1 2001/10/13 14:50:33 tilda + * Add string array code to unify handling of names / values. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_strings_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_strings.c,v 1.9 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include <common/types.h> + +#include <ctype.h> +#include <string.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * p_strlen() + * + * DESCRIPTION + * Find length of string. + * + * RETURNS + * Length of strings. + *----------------------------------------------------------------------------*/ + +int p_strlen( + const char *p_string /* String to measure */ + ) +{ +#if defined(HAVE_STRLEN) + return strlen(p_string); +#else + int len = 0; + + while (*p_string) + { + p_string++; + len++; + } + + return len; +#endif +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcpy() + * + * DESCRIPTION + * Copy string to buffer. + * + * RETURNS + * Pointer to buffer. + *----------------------------------------------------------------------------*/ + +char *p_strcpy( + char *p_string1, /* Buffer to copy to */ + const char *p_string2 /* String to copy */ + ) +{ +#if defined(HAVE_STRCPY) + return strcpy(p_string1, p_string2); +#else + char *p_return = p_string1; + + while ((*p_string1++ = *p_string2++)) + ; + + return p_return; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcmp() + * + * DESCRIPTION + * Case sensitive string comparison. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +int p_strcmp( + const char *p_string1, + const char *p_string2 + ) +{ +#if defined(HAVE_STRCMP) + return strcmp(p_string1, p_string2); +#else + while (*p_string1 && (*p_string1 == *p_string2)) + { + p_string1++; + p_string2++; + } + + return (*(unsigned char *)p_string1) - (*(unsigned char *)p_string2); +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcat() + * + * DESCRIPTION + * Append one string to another. + * + * RETURNS + * Pointer to resulting string. + *----------------------------------------------------------------------------*/ + +char *p_strcat( + char *p_string1, /* String to append to */ + const char *p_string2 /* String to append */ + ) +{ +#if defined(HAVE_STRCAT) + return strcat(p_string1, p_string2); +#else + char *p_return = p_string1; + + while (*p_string1) + p_string1++; + + while ((*p_string1++ = *p_string2++)) + ; + + return p_return; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strstr() + * + * DESCRIPTION + * Case sensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +char *p_strstr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ) +{ +#if defined(HAVE_STRSTR) + return strstr(p_searched, p_lookedfor); +#else + if (*p_searched == 0) + { + if (*p_lookedfor) + { + return (char *)NULL; + } + + return (char *)p_searched; + } + + while (*p_searched) + { + uint32_t i; + + for (i = 0;;i++) + { + if (p_lookedfor[i] == 0) + { + return (char *)p_searched; + } + + if (p_lookedfor[i] != p_searched[i]) + { + break; + } + } + + p_searched++; + } + + return (char *)NULL; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_stricmp() + * + * DESCRIPTION + * Case insensitive string comparison function. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +int p_stricmp( + const char *p_string1, /* First string */ + const char *p_string2 /* Second string */ + ) +{ +#if defined(HAVE_STRCASECMP) + return strcasecmp(p_string1, p_string2); +#elif defined(HAVE_STRICMP) + return stricmp(p_string1, p_string2); +#else + while (*p_string1 && (tolower(*p_string1) == tolower(*p_string2))) + { + p_string1++; + p_string2++; + } + + return tolower(*(unsigned char *)p_string1) - tolower(*(unsigned char *)p_string2); +#endif +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_stristr() + * + * DESCRIPTION + * Case insensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +char *p_stristr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ) +{ +#if defined(HAVE_STRISTR) + return strstr(p_searched, p_lookedfor); +#else + if (*p_searched == 0) + { + if (*p_lookedfor) + { + return (char *)NULL; + } + + return (char *)p_searched; + } + + while (*p_searched) + { + uint32_t i; + + for (i = 0;;i++) + { + if (p_lookedfor[i] == 0) + { + return (char *)p_searched; + } + + if (tolower(p_lookedfor[i]) != tolower(p_searched[i])) + { + break; + } + } + + p_searched++; + } + + return (char *)NULL; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_memcpy() + * + * DESCRIPTION + * Copy characetrs between buffers. No checks on overlap. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void p_memcpy( + void *p_destination, /* Pointer to buffer */ + const void *p_source, /* Source of copy */ + uint32_t length /* Number of characters to copy */ + ) +{ +#if defined(HAVE_MEMCPY) + memcpy(p_destination, p_source, length); +#else + uint8_t *p_dst = (uint8_t *)p_destination; + uint8_t *p_src = (uint8_t *)p_source; + + while (length--) + { + *p_dst++ = *p_src++; + } +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_memset() + * + * DESCRIPTION + * Fill buffer with indicated character. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void p_memset( + void *p_destination, /* Pointer to buffer */ + uint8_t v, /* Character to fill with */ + uint32_t length /* Length of buffer to set */ + ) +{ +#if defined(HAVE_MEMSET) + memset(p_destination, v, length); +#else + uint8_t *p_dst = (uint8_t *)p_destination; + + while (length--) + *p_dst++ = v; +#endif +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_strings.h b/src/vf_strings.h new file mode 100644 index 0000000..29ccd78 --- /dev/null +++ b/src/vf_strings.h @@ -0,0 +1,230 @@ +/******************************************************************************* + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.6 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + String handling functions. The library uses the p_ functions (where hopefully + the 'p' stands for 'portable') and they are provided here in terms of C runtime + functions or implemented explicitly. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_strings.h,v $ + * Revision 1.6 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.5 2002/10/08 21:27:20 tilda + * Correct #endif directive. + * + * Revision 1.4 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.3 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.2 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.1 2001/10/13 14:50:33 tilda + * Add string array code to unify handling of names / values. + * + *******************************************************************************/ + +#ifndef _VF_STRINGS_H_ +#define _VF_STRINGS_H_ + +#ifndef NORCSID +static const char vf_strings_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_strings.h,v 1.6 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * p_strlen() + * + * DESCRIPTION + * Find length of string. + * + * RETURNS + * Length of strings. + *----------------------------------------------------------------------------*/ + +extern int p_strlen( + const char *p_string /* String to measure */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcpy() + * + * DESCRIPTION + * Copy string to buffer. + * + * RETURNS + * Pointer to buffer. + *----------------------------------------------------------------------------*/ + +extern char *p_strcpy( + char *p_string1, /* Buffer to copy to */ + const char *p_string2 /* String to copy */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcmp() + * + * DESCRIPTION + * Case sensitive string comparison. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +extern int p_strcmp( + const char *p_string1, + const char *p_string2 + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcat() + * + * DESCRIPTION + * Append one string to another. + * + * RETURNS + * Pointer to resulting string. + *----------------------------------------------------------------------------*/ + +extern char *p_strcat( + char *p_string1, /* String to append to */ + const char *p_string2 /* String to append */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strstr() + * + * DESCRIPTION + * Case sensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +extern char *p_strstr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_stricmp() + * + * DESCRIPTION + * Case insensitive string comparison function. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +extern int p_stricmp( + const char *p_string1, /* First string */ + const char *p_string2 /* Second string */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_stristr() + * + * DESCRIPTION + * Case insensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +extern char *p_stristr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ); + +/*----------------------------------------------------------------------------* + * NAME + * p_memcpy() + * + * DESCRIPTION + * Copy characetrs between buffers. No checks on overlap. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void p_memcpy( + void *p_destination, /* Pointer to buffer */ + const void *p_source, /* Source of copy */ + uint32_t length /* Number of characters to copy */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_memset() + * + * DESCRIPTION + * Fill buffer with indicated character. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void p_memset( + void *p_destination, /* Pointer to buffer */ + uint8_t v, /* Character to fill with */ + uint32_t length /* Length of buffer to set */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_STRINGS_H_*/ diff --git a/src/vf_writer.c b/src/vf_writer.c new file mode 100644 index 0000000..ef3298a --- /dev/null +++ b/src/vf_writer.c @@ -0,0 +1,616 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.12 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + Code for writing vformat files. This is temporary as it is not based + around a state machine for converting the object to a character stream. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_writer.c,v $ + * Revision 1.12 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.11 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.10 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.9 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.8 2002/10/08 21:11:35 tilda + * Remove common.h. + * + * Revision 1.7 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.6 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.5 2001/11/18 21:45:10 tilda + * Add newline after BASE64 encodings + * + * Revision 1.4 2001/11/14 22:36:55 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.3 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_writer_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_writer.c,v 1.12 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include <common/types.h> + +#include <stdio.h> +#include <ctype.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include <vformat/vf_iface.h> + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_malloc.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define QPMAXPERLINE (76) +#define BASE64PERLINE (64) + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +static bool_t write_name_fields( + FILE *fp, + uint32_t *p_charsonline, + VPROP_T *p_prop + ); + +static void write_base64_chars( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t len /* buffer length */ + ); + +static bool_t write_quoted_printable( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t *p_charsonline /* Num on line so far */ + ); + +static char char_to_base64( + uint8_t b /* Byte to convert */ + ); + +static bool_t qp_needs_quoting( + uint8_t c /* Char to test */ + ); + +static bool_t write_vobject_to_file( + FILE *fp, + VOBJECT_T *p_object, + bool_t write_all + ); + +/*============================================================================* + Private Data + *============================================================================*/ + +static const char szEndOfLine[3] = { 0x0D, 0x0A, 0x00 }; + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_write_file() + * + * DESCRIPTION + * Write indicated vobject to file. + * + * RETURNS + * TRUE <=> written OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_write_file( + const char *p_name, /* Outpt filename */ + VF_OBJECT_T *p_object, /* The object to write */ + bool_t write_all /* Should write p_next as well? */ + ) +{ + FILE *fp; + bool_t ret = FALSE; + + fp = fopen(p_name, "wb"); + + if (fp) + { + ret = write_vobject_to_file(fp, (VOBJECT_T *)p_object, write_all); + + if (0 == fclose(fp)) + { + /* as is */ + } + else + { + ret = FALSE; + } + } + + return ret; +} + + + + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * write_vobject_to_file() + * + * DESCRIPTION + * Write each field of the indicated vformat object to the indicated FILE* + * invoking write_vobject_to_file() recursively if a field is found which + * contains a vformat object. + * + * RETURNS + * TRUE <=> file acces OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t write_vobject_to_file( + FILE *fp, + VOBJECT_T *p_object, + bool_t write_all + ) +{ + bool_t ret = TRUE; + + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + VPROP_T *p_props = p_obj->p_props; + + fprintf(fp, "%s:%s", VFP_BEGIN, p_obj->p_type); + + fprintf(fp, szEndOfLine); + + for (;NULL != p_props;p_props = p_props->p_next) + { + uint32_t charsonline; + + switch (p_props->value.encoding) + { + default: + case VF_ENC_7BIT: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + uint32_t n; + + for (n = 0;ret && (n < p_props->value.v.s.n_strings);n++) + { + if (n) + fprintf(fp, ";"); + + if (p_props->value.v.s.pp_strings[n]) + { + fprintf(fp, "%s", p_props->value.v.s.pp_strings[n]); + } + } + } + } + break; + + case VF_ENC_BASE64: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + write_base64_chars(fp, p_props->value.v.b.p_buffer, p_props->value.v.b.n_bufsize); + } + } + break; + + case VF_ENC_QUOTEDPRINTABLE: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + uint32_t n; + + for (n = 0;ret && (n < p_props->value.v.s.n_strings);n++) + { + if (n) + fprintf(fp, ";"); + + if (p_props->value.v.s.pp_strings[n]) + { + ret = write_quoted_printable(fp, p_props->value.v.s.pp_strings[n], &charsonline); + } + } + } + } + break; + + case VF_ENC_VOBJECT: + { + write_vobject_to_file(fp, p_props->value.v.o.p_object, TRUE); + } + break; + } + + if (VF_ENC_VOBJECT != p_props->value.encoding) + fprintf(fp, szEndOfLine); + } + + fprintf(fp, "%s:%s", VFP_END, p_obj->p_type); + + fprintf(fp, szEndOfLine); + + if (ret && p_obj->p_next && write_all) + { + ret = write_vobject_to_file(fp, p_obj->p_next, TRUE); + } + + p_obj->modified = !ret; + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_base64_chars() + * + * DESCRIPTION + * Write the indicated binary data stream out to FILE* using BASE64 + * encoding. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void write_base64_chars( + FILE *fp, /* File we're writing */ + uint8_t *p_buffer, /* Pointer to buffer */ + uint32_t n_chars /* buffer length */ + ) +{ + uint32_t posn; + char quad[5]; + uint8_t b; + + quad[4] = 0; + + for (posn = 0;posn < n_chars;) + { + int i; + uint32_t triplet = 0; + uint8_t bits = 0; + + /* Form triplet from data if available */ + + for (i = 0;i < 3;i++, posn++) + { + triplet = triplet << 8; + + if (posn < n_chars) + { + triplet |= *(p_buffer + posn); + + bits += 8; + } + } + + /* Convert the triplet to text */ + + for (i = 0;i < 4;i++) + { + b = (uint8_t)((0xFC0000 & triplet) >> 18); + + triplet = triplet << 6; + + quad[i] = (i <= (bits/6)) ? char_to_base64(b) : '='; + } + + /* Output the text prefixed by newlines if necessary */ + + if (((posn - 3) % (BASE64PERLINE / 4)) == 0) + { + fprintf(fp, szEndOfLine); + fprintf(fp, " "); + } + + fprintf(fp, "%s", quad); + } + + fprintf(fp, szEndOfLine); +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_quoted_printable() + * + * DESCRIPTION + * Write the indicated field back to the file in quoted printable format. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static bool_t write_quoted_printable( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t *p_charsonline /* Num on line so far */ + ) +{ + uint32_t i; + uint32_t charsonline = *p_charsonline; + + for (i = 0;s;i++) + { + uint8_t c = s[i]; + + if ('\0' == c) + { + break; + } + else + { + if (3 + charsonline > QPMAXPERLINE) + { + fprintf(fp, "="); + fprintf(fp, szEndOfLine); + charsonline = 0; + } + + if (qp_needs_quoting(c)) + { + fprintf(fp, "=%02X", c); + charsonline += 3; + + if (0x0D == c) + { + fprintf(fp, "="); + fprintf(fp, szEndOfLine); + charsonline = 0; + } + } + else + { + fprintf(fp, "%c", c); + charsonline += 1; + } + } + } + + *p_charsonline = charsonline; + + return TRUE; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * char_to_base64() + * + * DESCRIPTION + * Converts byte to BASE64. + * + * RETURNS + * Character encoded. + *----------------------------------------------------------------------------*/ + +static char char_to_base64( + uint8_t b /* Byte to convert */ + ) +{ + char ret; + + if (b < 26) + { + ret = (char)b + 'A'; + } + else + if (b < 52) + { + ret = (char)(b - 26) + 'a'; + } + else + if (b < 62) + { + ret = (char)(b - 52) + '0'; + } + else + if (b == 62) + { + ret = '+'; + } + else + { + ret = '/'; + } + + return ret; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * qp_needs_quoting() + * + * DESCRIPTION + * Works out of 'c' needs quoting in quoted printable format. + * + * RETURNS + * TRUE <=> need to quote. + *----------------------------------------------------------------------------*/ + +static bool_t qp_needs_quoting( + uint8_t c /* Char to test */ + ) +{ + /* TBD - look in the RFC?! */ + + bool_t needs_quoting = FALSE; + + switch (c) + { + case ' ': + case ',': + case '-': + case '.': + case '!': + case '?': + case '\'': + return FALSE; + + default: + if (isalnum(c)) + needs_quoting = FALSE; + else + needs_quoting = TRUE; + break; + } + + return needs_quoting; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_name_fields() + * + * DESCRIPTION + * Write name fields to file. + * + * RETURNS + * TRUE <=> OK so far. + *----------------------------------------------------------------------------*/ + +bool_t write_name_fields( + FILE *fp, + uint32_t *p_charsonline, + VPROP_T *p_prop + ) +{ + VSTRARRAY_T *p_strarray = &(p_prop->name); + bool_t ret = FALSE; + + *p_charsonline = 0; + + if (p_prop->p_group) + { + *p_charsonline += fprintf(fp, "%s.", p_prop->p_group); + } + + if (p_strarray->pp_strings) + { + uint32_t i; + + for (i = 0;i < p_strarray->n_strings;i++) + { + char *p_name_field = p_strarray->pp_strings[i]; + + if (p_name_field && (0 < p_strlen(p_name_field))) + { + if (0 < i) + { + fprintf(fp, ";"); + *p_charsonline += 1; + } + + *p_charsonline += fprintf(fp, "%s", p_name_field); + } + } + + fprintf(fp, ":"); + *p_charsonline += 1; + + ret = TRUE; + } + + return ret; +} + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/stamp-h.in diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..883a1a7 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,7 @@ +bin_PROGRAMS = vformat + +vformat_SOURCE = testsuppt.c vformat.c +vformat_LDADD = ../src/.libs/libvformat.a testsuppt.o + +EXTRA_DIST = testsuppt.c testsuppt.h tests/access/*.vcf tests/adhoc/*.vc* tests/spec/*.vcf tests/utf-8/*.vcf +TESTS = vformat
\ No newline at end of file diff --git a/test/tests/access/access_1.vcf b/test/tests/access/access_1.vcf new file mode 100644 index 0000000..ecb8636 --- /dev/null +++ b/test/tests/access/access_1.vcf @@ -0,0 +1,17 @@ +BEGIN:VCARD +N:frfrfr;frfrfr +TEL;HOME;PREF:123456789 +FN:Fr. Frfrfr (fr the frfrfr) +TEL;WORK;PREF:ABCDEFGHI +ORG:fr;fr;fr;fr +TEL;CELLULAR;PREF:JKLMNOP +SOUND;WAVE;BASE64: + UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC + eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK + jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2 +TEL;WORK:XXYYZZ!! +SOUND;WAVE;BASE64: + UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC + eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK + jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2 +END:VCARD diff --git a/test/tests/adhoc/group_1.vcf b/test/tests/adhoc/group_1.vcf new file mode 100644 index 0000000..c0ab6ef --- /dev/null +++ b/test/tests/adhoc/group_1.vcf @@ -0,0 +1,6 @@ +BEGIN:VCARD +N:aaa;bbb;ccc +A.N:ddd;eee;fff +B.N:ggg;hhh;iii +C.N:jjj;kkk;lll +END:VCARD diff --git a/test/tests/adhoc/group_2.vcf b/test/tests/adhoc/group_2.vcf new file mode 100644 index 0000000..bd5dad8 --- /dev/null +++ b/test/tests/adhoc/group_2.vcf @@ -0,0 +1,9 @@ +BEGIN:VCARD +N:aaa;bbb;ccc +X-1-FILLER:1;2;3;4;5;6;7;8 +A.N:ddd;eee;fff +X-2-FILLER:1;2;3;4;5;6;7;8 +B.N:ggg;hhh;iii +X-3-FILLER:1;2;3;4;5;6;7;8 +C.N:jjj;kkk;lll +END:VCARD diff --git a/test/tests/adhoc/group_3.vcf b/test/tests/adhoc/group_3.vcf new file mode 100644 index 0000000..7f278ad --- /dev/null +++ b/test/tests/adhoc/group_3.vcf @@ -0,0 +1,13 @@ +BEGIN:VCARD +N:aaa;bbb;ccc +FN:111;222;333 +X-1-FILLER:1;2;3;4;5;6;7;8 +A.N:ddd;eee;fff +A.FN:111ddd;222eee;222fff +X-2-FILLER:1;2;3;4;5;6;7;8 +B.N:ggg;hhh;iii +B.FN:111ggg;222hhh;333iii +X-3-FILLER:1;2;3;4;5;6;7;8 +C.N:jjj;kkk;lll +C.FN:111jjj;222kkk;333lll +END:VCARD diff --git a/test/tests/adhoc/group_4.vcf b/test/tests/adhoc/group_4.vcf new file mode 100644 index 0000000..23f9f06 --- /dev/null +++ b/test/tests/adhoc/group_4.vcf @@ -0,0 +1,16 @@ +BEGIN:VCARD +N:aaa;bbb;ccc +FN:111;222;333 +END:VCARD +BEGIN:VCARD +A.N:ddd;eee;fff +A.FN:111ddd;222eee;222fff +END:VCARD +BEGIN:VCARD +B.N:ggg;hhh;iii +B.FN:111ggg;222hhh;333iii +END:VCARD +BEGIN:VCARD +C.N:jjj;kkk;lll +C.FN:111jjj;222kkk;333lll +END:VCARD diff --git a/test/tests/adhoc/group_5.vcf b/test/tests/adhoc/group_5.vcf new file mode 100644 index 0000000..460777b --- /dev/null +++ b/test/tests/adhoc/group_5.vcf @@ -0,0 +1,16 @@ +BEGIN:VCARD +N:aaa;bbb;ccc +FN:111;222;333 +BEGIN:VCARD +A.N:ddd;eee;fff +A.FN:111ddd;222eee;222fff +BEGIN:VCARD +B.N:ggg;hhh;iii +B.FN:111ggg;222hhh;333iii +BEGIN:VCARD +C.N:jjj;kkk;lll +C.FN:111jjj;222kkk;333lll +END:VCARD +END:VCARD +END:VCARD +END:VCARD diff --git a/test/tests/adhoc/group_6.vcf b/test/tests/adhoc/group_6.vcf new file mode 100644 index 0000000..4e5bffe --- /dev/null +++ b/test/tests/adhoc/group_6.vcf @@ -0,0 +1,23 @@ +BEGIN:VCARD +X-DUMMY-1:123 +X-DUMMY-2:456 +X-DUMMY-3:789 +ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +ABC.X-DUMMY-1:123 +ABC.X-DUMMY-2:456 +ABC.X-DUMMY-3:789 +ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +DEF.X-DUMMY-1:123 +DEF.X-DUMMY-2:456 +DEF.X-DUMMY-3:789 +ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +END:VCARD diff --git a/test/tests/adhoc/group_7.vcf b/test/tests/adhoc/group_7.vcf new file mode 100644 index 0000000..9dcb356 --- /dev/null +++ b/test/tests/adhoc/group_7.vcf @@ -0,0 +1,46 @@ +BEGIN:VCARD +X-DUMMY-1:123 +DEF.X-DUMMY-1:123 +ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +ABC.X-DUMMY-1:123 +DEF.X-DUMMY-2:456 +X-DUMMY-2:456 +ABC.X-DUMMY-2:456 +ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +DEF.X-DUMMY-3:789 +X-DUMMY-3:789 +ABC.X-DUMMY-3:789 +ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +BEGIN:VCARD +PPP.X-DUMMY-1:123 +PPP.DEF.X-DUMMY-1:123 +PPP.ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +PPP.ABC.X-DUMMY-1:123 +PPP.DEF.X-DUMMY-2:456 +PPP.X-DUMMY-2:456 +PPP.ABC.X-DUMMY-2:456 +PPP.ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +PPP.DEF.X-DUMMY-3:789 +PPP.X-DUMMY-3:789 +PPP.ABC.X-DUMMY-3:789 +PPP.ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt= +END:VCARD +END:VCARD diff --git a/test/tests/adhoc/mail_list_1.vcf b/test/tests/adhoc/mail_list_1.vcf new file mode 100644 index 0000000..b211638 --- /dev/null +++ b/test/tests/adhoc/mail_list_1.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +TEL;CAR: +TEL;HOME;VOICE:123 +END:VCARD diff --git a/test/tests/adhoc/mail_list_2.vcf b/test/tests/adhoc/mail_list_2.vcf new file mode 100644 index 0000000..eacbd72 --- /dev/null +++ b/test/tests/adhoc/mail_list_2.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +ADR;WORK;ENCODING=QUOTED-PRINTABLE:;;HSBC Building=0A=0D= +30 Metcalfe Street, 3rd Floor;Ottawa;ON;K1P 5L4;Canada +END:VCARD diff --git a/test/tests/adhoc/mail_list_3.vcf b/test/tests/adhoc/mail_list_3.vcf new file mode 100644 index 0000000..5012c8b --- /dev/null +++ b/test/tests/adhoc/mail_list_3.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N;ENCODING=QUOTED-PRINTABLE;CHARSET=ISO-8859-1:Familyame=E4;Surname +END:VCARD diff --git a/test/tests/adhoc/mail_list_4.vcf b/test/tests/adhoc/mail_list_4.vcf new file mode 100644 index 0000000..dea6393 --- /dev/null +++ b/test/tests/adhoc/mail_list_4.vcf @@ -0,0 +1,13 @@ +BEGIN:VCARD +VERSION:2.1 +BEGIN:VCARD +UID:1 +N:Jerry Ramond +TEL:1-221-222-1123 +END:VCARD +BEGIN:VCARD +UID:2 +N:Lacy Ramond +TEL:1-212-222-1223 +END:VCARD +END:VCARD diff --git a/test/tests/adhoc/mail_list_5.vcf b/test/tests/adhoc/mail_list_5.vcf new file mode 100644 index 0000000..19ed460 --- /dev/null +++ b/test/tests/adhoc/mail_list_5.vcf @@ -0,0 +1,19 @@ +BEGIN:VCARD +VERSION:2.1 +X-DL;Design Work Group:List Item 1;List Item 2;List Item 3 +BEGIN:VCARD +UID:List Item 1 +N:John Smith +TEL:+1-213-555-1111 +END:VCARD +BEGIN:VCARD +UID:List Item 2 +N:I. M. Big +TEL:+1-213-555-9999 +END:VCARD +BEGIN:VCARD +UID:List Item 3 +N:Jane Doe +TEL:+1-213-555-5555 +END:VCARD +END:VCARD diff --git a/test/tests/adhoc/mail_list_6.vcf b/test/tests/adhoc/mail_list_6.vcf new file mode 100644 index 0000000..987350d --- /dev/null +++ b/test/tests/adhoc/mail_list_6.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N;ENCODING=QUOTED-PRINTABLE:Last;First;Middle +N:Last;First;Middle +END:VCARD diff --git a/test/tests/adhoc/multiple_objs_1.vcf b/test/tests/adhoc/multiple_objs_1.vcf new file mode 100644 index 0000000..f6d69ef --- /dev/null +++ b/test/tests/adhoc/multiple_objs_1.vcf @@ -0,0 +1,21 @@ +BEGIN:VCARD +STUF;QUOTED-PRINTABLE:Come And Get It! +END:VCARD + +BEGIN:VCARD +MORE-STUF;QUOTED-PRINTABLE:Come And Get It! +END:VCARD + +BEGIN:VCARD +YET-MORE-STUF;QUOTED-PRINTABLE:Come And Get It! +END:VCARD + +BEGIN:VCARD +AND-YET-SOME-MORE-STUF;QUOTED-PRINTABLE:Come And Get It! + +BEGIN:VCARD +YET-MORE-STUF;QUOTED-PRINTABLE:Come And Get It! +END:VCARD + +END:VCARD + diff --git a/test/tests/adhoc/straight_1.vcf b/test/tests/adhoc/straight_1.vcf new file mode 100644 index 0000000..d4413f3 --- /dev/null +++ b/test/tests/adhoc/straight_1.vcf @@ -0,0 +1,2 @@ +BEGIN:VCARD +END:VCARD diff --git a/test/tests/adhoc/straight_2.vcf b/test/tests/adhoc/straight_2.vcf new file mode 100644 index 0000000..50ac599 --- /dev/null +++ b/test/tests/adhoc/straight_2.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:aaaa +END:VCARD diff --git a/test/tests/adhoc/straight_3.vcf b/test/tests/adhoc/straight_3.vcf new file mode 100644 index 0000000..bed344f --- /dev/null +++ b/test/tests/adhoc/straight_3.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:aaaa;bbbb +END:VCARD diff --git a/test/tests/adhoc/straight_4.vcf b/test/tests/adhoc/straight_4.vcf new file mode 100644 index 0000000..ce8b613 --- /dev/null +++ b/test/tests/adhoc/straight_4.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:aaaa;bbbb;cccc +END:VCARD diff --git a/test/tests/adhoc/straight_5.vcf b/test/tests/adhoc/straight_5.vcf new file mode 100644 index 0000000..b45a355 --- /dev/null +++ b/test/tests/adhoc/straight_5.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:;bbbb;cccc +END:VCARD diff --git a/test/tests/adhoc/straight_6.vcf b/test/tests/adhoc/straight_6.vcf new file mode 100644 index 0000000..84438f3 --- /dev/null +++ b/test/tests/adhoc/straight_6.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:;;cccc +END:VCARD diff --git a/test/tests/adhoc/straight_7.vcf b/test/tests/adhoc/straight_7.vcf new file mode 100644 index 0000000..2907949 --- /dev/null +++ b/test/tests/adhoc/straight_7.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +N:;bbbb; +END:VCARD diff --git a/test/tests/adhoc/straight_8.vcf b/test/tests/adhoc/straight_8.vcf new file mode 100644 index 0000000..165f956 --- /dev/null +++ b/test/tests/adhoc/straight_8.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +FN:12. 345678 987654321 +N:;bbbb; +END:VCARD diff --git a/test/tests/adhoc/straight_9.vcf b/test/tests/adhoc/straight_9.vcf new file mode 100644 index 0000000..d16729d --- /dev/null +++ b/test/tests/adhoc/straight_9.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N:;bbbb; +FN:12. 345678 987654321 +END:VCARD diff --git a/test/tests/adhoc/straight_A.vcf b/test/tests/adhoc/straight_A.vcf new file mode 100644 index 0000000..2f6a4f5 --- /dev/null +++ b/test/tests/adhoc/straight_A.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +X-DUMMY-1:123 +X-DUMMY-2:456 +X-DUMMY-3:789 +N:;bbbb; +FN:12. 345678 987654321 +END:VCARD diff --git a/test/tests/adhoc/straight_B.vcf b/test/tests/adhoc/straight_B.vcf new file mode 100644 index 0000000..49f79a3 --- /dev/null +++ b/test/tests/adhoc/straight_B.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N;qqq:;bbbb; +FN:12. 345678 987654321 +END:VCARD diff --git a/test/tests/adhoc/straight_C.vcf b/test/tests/adhoc/straight_C.vcf new file mode 100644 index 0000000..51ae8ff --- /dev/null +++ b/test/tests/adhoc/straight_C.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N;qqq;rrr;sss:;bbbb; +FN:12. 345678 987654321 +END:VCARD diff --git a/test/tests/adhoc/straight_D.vcf b/test/tests/adhoc/straight_D.vcf new file mode 100644 index 0000000..ae90513 --- /dev/null +++ b/test/tests/adhoc/straight_D.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N;qqq;rrr;sss:aaa;bbbb;ccc +FN:12. 345678 987654321 +END:VCARD diff --git a/test/tests/adhoc/straight_E.vcf b/test/tests/adhoc/straight_E.vcf new file mode 100644 index 0000000..71e53c9 --- /dev/null +++ b/test/tests/adhoc/straight_E.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +FN:12. 345678 987654321 +N;qqq;rrr;sss:;;ccc +END:VCARD diff --git a/test/tests/adhoc/straight_F.vcf b/test/tests/adhoc/straight_F.vcf new file mode 100644 index 0000000..530ff82 --- /dev/null +++ b/test/tests/adhoc/straight_F.vcf @@ -0,0 +1,5 @@ +BEGIN:VCARD +FN:12. 345678 987654321 +X;Y;Z:123123123 +N;qqq;rrr;sss:;;ccc +END:VCARD diff --git a/test/tests/adhoc/straight_G.vcf b/test/tests/adhoc/straight_G.vcf new file mode 100644 index 0000000..1cc3d18 --- /dev/null +++ b/test/tests/adhoc/straight_G.vcf @@ -0,0 +1,8 @@ +BEGIN:VCARD +A: +B: +C;D: +E:; +F;G:; +H;I;J:;K;L;M +END:VCARD diff --git a/test/tests/adhoc/straight_H.vcf b/test/tests/adhoc/straight_H.vcf new file mode 100644 index 0000000..d507d3f --- /dev/null +++ b/test/tests/adhoc/straight_H.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +A: +B: +C;D: +E:; +F;G:; +H;I;J:;K;L;M +N;;: +O;;;:;;P +Q;;;:;;R;;;S +END:VCARD diff --git a/test/tests/adhoc/straight_I.vcf b/test/tests/adhoc/straight_I.vcf new file mode 100644 index 0000000..298e613 --- /dev/null +++ b/test/tests/adhoc/straight_I.vcf @@ -0,0 +1,12 @@ +BEGIN:VCARD +A;QUOTED-PRINTABLE: +B;QUOTED-PRINTABLE: +C;QUOTED-PRINTABLE;D: +E;;;QUOTED-PRINTABLE:; +F;;;;;QUOTED-PRINTABLE;;;G:; +H;I;J;QUOTED-PRINTABLE:;K;L;M +N;QUOTED-PRINTABLE;;: +O;QUOTED-PRINTABLE;;;:;;P +Q;QUOTED-PRINTABLE;;;:;;R;;;S +T;QUOTED-PRINTABLE:;;UUU;VVV=12=12=12 +END:VCARD diff --git a/test/tests/adhoc/straight_qp_1.vcf b/test/tests/adhoc/straight_qp_1.vcf new file mode 100644 index 0000000..04fac0a --- /dev/null +++ b/test/tests/adhoc/straight_qp_1.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah +END:VCARD diff --git a/test/tests/adhoc/straight_qp_2.vcf b/test/tests/adhoc/straight_qp_2.vcf new file mode 100644 index 0000000..dcdbe3c --- /dev/null +++ b/test/tests/adhoc/straight_qp_2.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48 +END:VCARD diff --git a/test/tests/adhoc/straight_qp_3.vcf b/test/tests/adhoc/straight_qp_3.vcf new file mode 100644 index 0000000..4b858ff --- /dev/null +++ b/test/tests/adhoc/straight_qp_3.vcf @@ -0,0 +1,5 @@ +BEGIN:VCARD +ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48= +-ah-ah-ah-ah-ah-ah-ah-ah-=41=48=0D=0A= +-ah-ah-ah-ah-ah-ah-ah-ah-=41=48 +END:VCARD diff --git a/test/tests/adhoc/straight_qp_4.vcf b/test/tests/adhoc/straight_qp_4.vcf new file mode 100644 index 0000000..4b858ff --- /dev/null +++ b/test/tests/adhoc/straight_qp_4.vcf @@ -0,0 +1,5 @@ +BEGIN:VCARD +ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48= +-ah-ah-ah-ah-ah-ah-ah-ah-=41=48=0D=0A= +-ah-ah-ah-ah-ah-ah-ah-ah-=41=48 +END:VCARD diff --git a/test/tests/adhoc/vcal_1.vcs b/test/tests/adhoc/vcal_1.vcs new file mode 100644 index 0000000..aba139a --- /dev/null +++ b/test/tests/adhoc/vcal_1.vcs @@ -0,0 +1,20 @@ +BEGIN:VCALENDAR +VERSION:1.0 + +BEGIN:VEVENT +CATEGORIES:MEETING +STATUS:NEEDS ACTION +DTSTART:19960401T073000Z +DTEND:19960401T083000Z +SUMMARY:Steve's Proposal Review +DESCRIPTION:Steve and John to review newest proposal material +CLASS:PRIVATE +END:VEVENT + +BEGIN:VTODO +SUMMARY:John to pay for lunch +DUE:19960401T083000Z +STATUS:NEEDS ACTION +END:VTODO + +END:VCALENDAR diff --git a/test/tests/spec/2_1_1-begin-1.vcf b/test/tests/spec/2_1_1-begin-1.vcf new file mode 100644 index 0000000..36123a5 --- /dev/null +++ b/test/tests/spec/2_1_1-begin-1.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +X-HERE-IT-IS:fred +END:VCARD diff --git a/test/tests/spec/2_1_1-begin-2.vcf b/test/tests/spec/2_1_1-begin-2.vcf new file mode 100644 index 0000000..497bd3d --- /dev/null +++ b/test/tests/spec/2_1_1-begin-2.vcf @@ -0,0 +1,23 @@ +yv vuyg duvy gvuysdfgvdvgosdf gvouyvg uyv ouvgsd ovuydgs vudov dvuyg +vdovd vuhdpvduh vpdhv pdiv +sd vdosv dsvuh dvuh vdvpdu ivhd +sdvoidusvodsvdvdovd + +BEGIN:VCARD +X-HERE-IT-IS:fred +END:VCARD + +vdvdpfkvo +vkof +dfk +dfkvfd +vokdf +vdfkvdf +ovkdf +vokdf +vodk +ko + +BEGIN:VCARD +X-HERE-IT-IS:bloggs +END:VCARD diff --git a/test/tests/spec/2_1_2-property.vcf b/test/tests/spec/2_1_2-property.vcf new file mode 100644 index 0000000..934b2b9 --- /dev/null +++ b/test/tests/spec/2_1_2-property.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +TEL;HOME:+1-919-555-1234 +NOTE;ENCODING=QUOTED-PRINTABLE:Don't remember to order Girl= + Scout cookies from Stacey today! +NOTE;QUOTED-PRINTABLE:Don't remember to order Girl= + Scout cookies from Stacey today! +END:VCARD diff --git a/test/tests/spec/2_1_3-delimiters.vcf b/test/tests/spec/2_1_3-delimiters.vcf new file mode 100644 index 0000000..cacec9e --- /dev/null +++ b/test/tests/spec/2_1_3-delimiters.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +NOTE_1:This is a very long description that exists on a long line. +NOTE_2:This is a very long description + that exists on a long line. +NOTE_2:This is a very long description + that exists on a long line. +END:VCARD diff --git a/test/tests/spec/2_1_4_1-grouping-nested.vcf b/test/tests/spec/2_1_4_1-grouping-nested.vcf new file mode 100644 index 0000000..15d0aae --- /dev/null +++ b/test/tests/spec/2_1_4_1-grouping-nested.vcf @@ -0,0 +1,9 @@ +BEGIN:VCARD +N:abc;def;ghi +BEGIN:VCARD +N:jkl;mno;pqr +BEGIN:VCARD +N:stu;vwx;yz +END:VCARD +END:VCARD +END:VCARD diff --git a/test/tests/spec/2_1_4_1-grouping-sequential.vcf b/test/tests/spec/2_1_4_1-grouping-sequential.vcf new file mode 100644 index 0000000..72bfb23 --- /dev/null +++ b/test/tests/spec/2_1_4_1-grouping-sequential.vcf @@ -0,0 +1,9 @@ +BEGIN:VCARD +N:abc;def;ghi +END:VCARD +BEGIN:VCARD +N:jkl;mno;pqr +END:VCARD +BEGIN:VCARD +N:stu;vwx;yz +END:VCARD diff --git a/test/tests/spec/2_1_4_2-property-grouping.vcf b/test/tests/spec/2_1_4_2-property-grouping.vcf new file mode 100644 index 0000000..7abd856 --- /dev/null +++ b/test/tests/spec/2_1_4_2-property-grouping.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +A.TEL;HOME:+1-213-555-1234 +A.NOTE:This is my vacation home. +END:VCARD diff --git a/test/tests/spec/2_1_6-charset.vcf b/test/tests/spec/2_1_6-charset.vcf new file mode 100644 index 0000000..4be0ecf --- /dev/null +++ b/test/tests/spec/2_1_6-charset.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ADR;CHARSET=ISO-8859-8:... +END:VCARD diff --git a/test/tests/spec/2_1_7-language.vcf b/test/tests/spec/2_1_7-language.vcf new file mode 100644 index 0000000..d561fb2 --- /dev/null +++ b/test/tests/spec/2_1_7-language.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ADR;LANGUAGE=fr-CA:... +END:VCARD diff --git a/test/tests/spec/2_1_8-valuelocation.vcf b/test/tests/spec/2_1_8-valuelocation.vcf new file mode 100644 index 0000000..1ca41b6 --- /dev/null +++ b/test/tests/spec/2_1_8-valuelocation.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +PHOTO;VALUE=URL;TYPE=GIF:http://www.abc.com/dir_photos/my_photo.gif +SOUND;VALUE=CONTENT-ID:<jsmith.part3.960817T083000.xyzMail@host1.com> +END:VCARD diff --git a/test/tests/spec/2_2_1-fn.vcf b/test/tests/spec/2_2_1-fn.vcf new file mode 100644 index 0000000..fa6df57 --- /dev/null +++ b/test/tests/spec/2_2_1-fn.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +FN:Mr. John Q. Public, Esq. +END:VCARD diff --git a/test/tests/spec/2_2_2-name.vcf b/test/tests/spec/2_2_2-name.vcf new file mode 100644 index 0000000..deb7774 --- /dev/null +++ b/test/tests/spec/2_2_2-name.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +N:Public;John;Quinlan;Mr.;Esq. +N:Veni, Vidi, Vici;The Restaurant. +END:VCARD diff --git a/test/tests/spec/2_2_3-photo.vcf b/test/tests/spec/2_2_3-photo.vcf new file mode 100644 index 0000000..cb77196 --- /dev/null +++ b/test/tests/spec/2_2_3-photo.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +PHOTO;VALUE=URL:file:///jqpublic.gif +PHOTO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHtz +END:VCARD diff --git a/test/tests/spec/2_2_4-birthdate.vcf b/test/tests/spec/2_2_4-birthdate.vcf new file mode 100644 index 0000000..996a303 --- /dev/null +++ b/test/tests/spec/2_2_4-birthdate.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +BDAY:19950415 +BDAY:1995-04-15 +END:VCARD diff --git a/test/tests/spec/2_3_1-address.vcf b/test/tests/spec/2_3_1-address.vcf new file mode 100644 index 0000000..c7fb5f0 --- /dev/null +++ b/test/tests/spec/2_3_1-address.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ADR;DOM;WORK;HOME;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234; +END:VCARD diff --git a/test/tests/spec/2_3_2-label.vcf b/test/tests/spec/2_3_2-label.vcf new file mode 100644 index 0000000..0c5330d --- /dev/null +++ b/test/tests/spec/2_3_2-label.vcf @@ -0,0 +1,12 @@ +BEGIN:VCARD +LABEL;DOM;POSTAL;ENCODING=QUOTED-PRINTABLE:P. O. Box 456=0D=0A= +123 Main Street=0D=0A= +Any Town, CA 91921-1234 +LABEL;INTL;PARCEL,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= +123 Main Street=0D=0A= +Any Town, CA 91921-1234=0D=0A= +U.S.A. +LABEL;DOM;HOME,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A= +123 Main Street=0D=0A= +Any Town, CA 91921-1234 +END:VCARD diff --git a/test/tests/spec/2_4_1-tel.vcf b/test/tests/spec/2_4_1-tel.vcf new file mode 100644 index 0000000..ef68044 --- /dev/null +++ b/test/tests/spec/2_4_1-tel.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +TEL;WORK;HOME;VOICE;FAX:+1-800-555-1234 +END:VCARD diff --git a/test/tests/spec/2_4_2-email.vcf b/test/tests/spec/2_4_2-email.vcf new file mode 100644 index 0000000..020e419 --- /dev/null +++ b/test/tests/spec/2_4_2-email.vcf @@ -0,0 +1,16 @@ +BEGIN:VCARD +EMAIL;INTERNET:john.public@abc.com +EMAIL;TYPE=INTERNET:john.public@abc.com +EMAIL;TYPE=AppleLink:john.public@abc.com +EMAIL;TYPE=ATTMail:john.public@abc.com +EMAIL;TYPE=CIS:john.public@abc.com +EMAIL;TYPE=eWorld:john.public@abc.com +EMAIL;TYPE=INTERNET:john.public@abc.com +EMAIL;TYPE=IBMMail:john.public@abc.com +EMAIL;TYPE=MCIMail:john.public@abc.com +EMAIL;TYPE=POWERSHARE:john.public@abc.com +EMAIL;TYPE=PRODIGY:john.public@abc.com +EMAIL;TYPE=TLX:john.public@abc.com +EMAIL;TYPE=X400:john.public@abc.com +END:VCARD + diff --git a/test/tests/spec/2_4_3-mailer.vcf b/test/tests/spec/2_4_3-mailer.vcf new file mode 100644 index 0000000..bdec58f --- /dev/null +++ b/test/tests/spec/2_4_3-mailer.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +MAILER:ccMail 2.2 +END:VCARD diff --git a/test/tests/spec/2_4_5-tz.vcf b/test/tests/spec/2_4_5-tz.vcf new file mode 100644 index 0000000..6ceb500 --- /dev/null +++ b/test/tests/spec/2_4_5-tz.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +TZ:-0500 +TZ:-08:00 +END:VCARD diff --git a/test/tests/spec/2_4_6-geo.vcf b/test/tests/spec/2_4_6-geo.vcf new file mode 100644 index 0000000..8fdcde9 --- /dev/null +++ b/test/tests/spec/2_4_6-geo.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +GEO:37.24,-17.87 +END:VCARD diff --git a/test/tests/spec/2_5_1-title.vcf b/test/tests/spec/2_5_1-title.vcf new file mode 100644 index 0000000..12a6d70 --- /dev/null +++ b/test/tests/spec/2_5_1-title.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +TITLE:V.P., Research and Development +END:VCARD diff --git a/test/tests/spec/2_5_2-role.vcf b/test/tests/spec/2_5_2-role.vcf new file mode 100644 index 0000000..9aeb431 --- /dev/null +++ b/test/tests/spec/2_5_2-role.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ROLE:Executive +END:VCARD diff --git a/test/tests/spec/2_5_3-logo.vcf b/test/tests/spec/2_5_3-logo.vcf new file mode 100644 index 0000000..d740429 --- /dev/null +++ b/test/tests/spec/2_5_3-logo.vcf @@ -0,0 +1,6 @@ +BEGIN:VCARD +LOGO;ENCODING=BASE64;TYPE=GIF: + R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM + SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1 + 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHtz +END:VCARD diff --git a/test/tests/spec/2_5_4-agent.vcf b/test/tests/spec/2_5_4-agent.vcf new file mode 100644 index 0000000..af79284 --- /dev/null +++ b/test/tests/spec/2_5_4-agent.vcf @@ -0,0 +1,9 @@ +BEGIN:VCARD +AGENT: +BEGIN:VCARD +VERSION:2.1 +N:Friday;Fred +TEL;WORK;VOICE:+1-213-555-1234 +TEL;WORK;FAX:+1-213-555-5678 +END:VCARD +END:VCARD diff --git a/test/tests/spec/2_5_5-org.vcf b/test/tests/spec/2_5_5-org.vcf new file mode 100644 index 0000000..49ed921 --- /dev/null +++ b/test/tests/spec/2_5_5-org.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +ORG:ABC, Inc.;North American Division;Marketing +END:VCARD diff --git a/test/tests/spec/2_6_1-comment.vcf b/test/tests/spec/2_6_1-comment.vcf new file mode 100644 index 0000000..0573597 --- /dev/null +++ b/test/tests/spec/2_6_1-comment.vcf @@ -0,0 +1,6 @@ +BEGIN:VCARD +NOTE;ENCODING=QUOTED-PRINTABLE:This facsimile machine if operational= + 0830 to 1715 hours=0D=0A= +Monday through Friday. Call +1-213-555-1234 if you have problems=0D=0A= +with access to the machine. +END:VCARD diff --git a/test/tests/spec/2_6_2-revision.vcf b/test/tests/spec/2_6_2-revision.vcf new file mode 100644 index 0000000..f61aff7 --- /dev/null +++ b/test/tests/spec/2_6_2-revision.vcf @@ -0,0 +1,4 @@ +BEGIN:VCARD +REV:19951031T222710 +REV:1995-10-31T22:27:10Z +END:VCARD diff --git a/test/tests/spec/2_6_3-sound.vcf b/test/tests/spec/2_6_3-sound.vcf new file mode 100644 index 0000000..fd4cffe --- /dev/null +++ b/test/tests/spec/2_6_3-sound.vcf @@ -0,0 +1,8 @@ +BEGIN:VCARD +SOUND:JON Q PUBLIK +SOUND;VALUE=URL:file///multimed/audio/jqpublic.wav +SOUND;WAVE;BASE64: + UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC + eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK + jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2 +END:VCARD diff --git a/test/tests/spec/2_6_4-url.vcf b/test/tests/spec/2_6_4-url.vcf new file mode 100644 index 0000000..6b0e080 --- /dev/null +++ b/test/tests/spec/2_6_4-url.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +URL:http://abc.com/pub/directory/northam/jpublic.ecd +END:VCARD diff --git a/test/tests/spec/2_6_5-uid.vcf b/test/tests/spec/2_6_5-uid.vcf new file mode 100644 index 0000000..ae32da3 --- /dev/null +++ b/test/tests/spec/2_6_5-uid.vcf @@ -0,0 +1,3 @@ +BEGIN:VCARD +UID:19950401-080045-40000F192713-0052 +END:VCARD diff --git a/test/tests/utf-8/S15cx8.vcf b/test/tests/utf-8/S15cx8.vcf new file mode 100644 index 0000000..b4b796f --- /dev/null +++ b/test/tests/utf-8/S15cx8.vcf @@ -0,0 +1,352 @@ +BEGIN:VCARD +LOGO;GIF;BASE64;INLINE: + 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 + LNOjPNE8LbMpPT0c3dOyHNTpKNRGHccJAAA7 + +SOUND;URL:http://www.sounds.com +LABEL;DOM;QUOTED-PRINTABLE:=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2=A2=C3=91=C3=AC= +=C2=A2 +SOUND: +VERSION:2.1 +X-ESI-CATEGORIES:Keine Gruppe +NAME;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:Anon;H=C3=A4p +ADR;CHARSET=UTF-8:;;£;¥;;; +ORG;CHARSET=UTF-8:Näbert€€; +X-VFORMAT-POSNS:ORG@0x0;LABEL@0x-503;FN@14200x-503;LOGO@250x-6853 +FN: +N:;; +TITLE: +LABEL;QUOTED-PRINTABLE:=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2= +=A2 +END:VCARD diff --git a/test/tests/utf-8/S15cxu.vcf b/test/tests/utf-8/S15cxu.vcf new file mode 100644 index 0000000..a80c39e --- /dev/null +++ b/test/tests/utf-8/S15cxu.vcf @@ -0,0 +1,6 @@ +BEGIN:VCARD +VERSION:2.1 +X-ESI-CATEGORIES:Keine Gruppe +N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:B=C3=BCro +TEL;HOME:+12345678 +END:VCARD diff --git a/test/testsuppt.c b/test/testsuppt.c new file mode 100644 index 0000000..1a678d5 --- /dev/null +++ b/test/testsuppt.c @@ -0,0 +1,409 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile: vf_access.c $ + $Revision: 1.7 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + See accompanying header file. + +REFERENCES + (none) + +MODIFICATION HISTORY + $Log: testsuppt.c,v $ + Revision 1.7 2002/11/15 09:20:58 tilda + IID638823 - Don't include unistd.h unless required. + + Revision 1.6 2002/11/15 09:14:59 tilda + IID638823 - Various portability issues. + + Revision 1.5 2002/11/14 20:14:24 tilda + Minot tidy ups to WIN32 versions. + + Revision 1.4 2002/11/11 17:23:07 monos + run testing harness on linux systems + + Revision 1.3 2001/10/24 18:40:25 tilda + FindClose() not CloseHandle(). Nit. + + Revision 1.2 2001/10/14 19:53:36 tilda + Group handling. NO group searching functions. + + Revision 1.1 2001/10/12 19:02:15 tilda + Moved generic test functions to new file + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_access_c_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/testsuppt.c,v 1.7 2002/11/15 09:20:58 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <stdlib.h> +#if defined(HAS_UNISTD_H) +#include <unistd.h> +#endif +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <string.h> + +#if defined(WIN) || defined(WIN32) +#include <io.h> +#endif + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "testsuppt.h" + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ + +static int ts_nextfile; + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * find_first_file() + * + * DESCRIPTION + * Locate (initialise search for) first file of indicated pattern in + * directory. See also find_next_file(). + * + * RETURNS + * TRUE <=> first file found, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t find_first_file( + char *p_name, /* Name of file found (output) */ + file_enum_t *p_enum, /* Pointer to enumerator */ + const char *p_dirname, /* Directory we're searching in */ + const char *p_pattern /* Pattern we're searching for */ + ) +{ + bool_t ret = FALSE; + char pattern[_MAX_PATH]; + + sprintf(pattern, "%s//%s", p_dirname, p_pattern); + + if (p_enum) + { + memset(p_enum, '\0', sizeof(*p_enum)); + +#if defined(WIN) || defined(WIN32) + + p_enum->h = INVALID_HANDLE_VALUE; + + if (INVALID_HANDLE_VALUE == (p_enum->h = FindFirstFile(pattern, &p_enum->fd))) + { + /* No files */ + } + else + { + p_enum->p_dirname = strdup(p_dirname); + + if (p_enum->p_dirname) + { + sprintf(p_name, "%s//%s", p_enum->p_dirname, p_enum->fd.cFileName); + + ret = TRUE; + } + else + { + close_file_find(p_enum); + } + } +#else + if (0 == glob(pattern, GLOB_ERR, NULL, &p_enum->h)) + { + /* Return first found pathname and increment counter */ + sprintf(p_name, "%s", p_enum->h.gl_pathv[0]); + ts_nextfile = 1; + + ret = TRUE; + } + else + { + /* Failed to open directory or to find files */ + } +#endif + } + + return ret; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * find_next_file() + * + * DESCRIPTION + * Locate (initialise search for) first file of indicated pattern in + * directory. See also find_first_file(). + * + * RETURNS + * TRUE <=> next file found, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t find_next_file( + char *p_name, /* Name of file found (output) */ + file_enum_t *p_enum /* Pointer to enumerator */ + ) +{ + bool_t ret = FALSE; + + if (p_enum) + { +#if defined(WIN) || defined(WIN32) + if (INVALID_HANDLE_VALUE == p_enum->h) + { + /* No files */ + } + else + { + if (FindNextFile(p_enum->h, &p_enum->fd)) + { + sprintf(p_name, "%s//%s", p_enum->p_dirname, p_enum->fd.cFileName); + + ret = TRUE; + } + } +#else + if (ts_nextfile < p_enum->h.gl_pathc) + { + sprintf(p_name, "%s", p_enum->h.gl_pathv[ts_nextfile++]); + ret = TRUE; + } +#endif + } + + return ret; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * close_file_find() + * + * DESCRIPTION + * Close the file search. Free memory, close handles etc. The enumerator + * is ready for another call to find_first_file(). + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void close_file_find( + file_enum_t *p_enum /* Pointer to enumerator */ + ) +{ + if (p_enum) + { +#if defined(WIN) || defined(WIN32) + if (INVALID_HANDLE_VALUE == p_enum->h) + { + /* Not an open handle */ + } + else + { + FindClose(p_enum->h); + p_enum->h = INVALID_HANDLE_VALUE; + } + + if (p_enum->p_dirname) + { + free(p_enum->p_dirname); + p_enum->p_dirname = NULL; + } +#else + globfree(&p_enum->h); +#endif + } +} + + + +/*----------------------------------------------------------------------------* + * NAME + * filecomp() + * + * DESCRIPTION + * Compare files. + * + * RETURNS + * 0 <=> fies are th same, != 0 else. + *----------------------------------------------------------------------------*/ + +int filecomp( + const char *p_file1, /* Name of first file */ + const char *p_file2 /* Name of second file */ + ) +{ + int ret = (-1); + file_image_t f1, f2; + + if (get_file_image(&f1, p_file1)) + { + if (get_file_image(&f2, p_file2)) + { + if (f1.size == f2.size) + { + ret = memcmp(f1.p_data, f2.p_data, f1.size); + } + else + { + printf(" Sizes difference :\n %s (%lu bytes) Vs.\n %s (%lu bytes)\n", + p_file1, (unsigned long)f1.size, p_file2, (unsigned long)f2.size); + } + + free_file_image(&f2); + } + + free_file_image(&f1); + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * get_file_image() + * + * DESCRIPTION + * Load file into memory. + * + * RETURNS + * TRUE <=> file i/o successful, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t get_file_image( + file_image_t *p, /* Info on file (output) */ + const char *p_name /* Name of file */ + ) +{ + bool_t ret = FALSE; + + if (p) + { + struct stat buf; + + memset(p, '\0', sizeof(*p)); + + if (0 == stat(p_name, &buf)) + { + p->size = buf.st_size; + p->p_data = malloc(p->size); + + if (p->p_data) + { + FILE *fp; + + fp = fopen(p_name, "rb"); + + if (fp) + { + if (p->size == (size_t)read(fileno(fp), p->p_data, p->size)) + { + ret = TRUE; + } + + fclose(fp); + } + } + } + } + + return ret; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * free_file_image() + * + * DESCRIPTION + * Free up resources allocated to a file image. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void free_file_image( + file_image_t *p /* Info on file (output) */ + ) +{ + if (p) + { + if (p->p_data) + { + free(p->p_data); + p->p_data = NULL; + } + + p->size = 0l; + } +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + FIN + *============================================================================*/ diff --git a/test/testsuppt.h b/test/testsuppt.h new file mode 100644 index 0000000..142a676 --- /dev/null +++ b/test/testsuppt.h @@ -0,0 +1,211 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.3 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Platform dependant functions supporting vformat library test harness. + + A typical usage for the file find functions is as follows: + + if (find_first_file(...)) + { + do + { + something_worthwhile(); + } + while (find_next_file(...)) + ; + + close_file_find(...); + } + + The only reason this exists is 'cos I like to keep the core test harness + code platform independant. + +REFERENCES + (none) + +MODIFICATION HISTORY + $Log: testsuppt.h,v $ + Revision 1.3 2002/11/14 20:14:25 tilda + Minot tidy ups to WIN32 versions. + + Revision 1.2 2002/11/11 17:23:08 monos + run testing harness on linux systems + + Revision 1.1 2001/10/12 19:02:15 tilda + Moved generic test functions to new file + * + *******************************************************************************/ + +#ifndef NORCSID +static const char testsuppt_h_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/testsuppt.h,v 1.3 2002/11/14 20:14:25 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *=============================================================================*/ + +#if defined(WIN) || defined(WIN32) +#include <Windows.h> +#else +#include <glob.h> +#endif + +/*============================================================================* + Public Defines + *============================================================================*/ + +#ifndef _MAX_PATH +#define _MAX_PATH (256) +#endif + +/*============================================================================* + Private Data Types + *============================================================================*/ + +typedef struct +{ +#if defined(WIN) || defined(WIN32) + WIN32_FIND_DATA fd; + HANDLE h; + char *p_dirname; +#else + glob_t h; +#endif +} +file_enum_t; + +typedef struct +{ + size_t size; + char *p_data; +} +file_image_t; + +/*============================================================================* + Public Functions + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * find_first_file() + * + * DESCRIPTION + * Locate (initialise search for) first file of indicated pattern in + * directory. If find_first_file() returns TRUE, users should call + * do whatever they wer going to do with the file that's located and + * then continue their search using find_next_file(). + * + * RETURNS + * TRUE <=> first file found, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t find_first_file( + char *p_name, /* Name of file found (output) */ + file_enum_t *p_enum, /* Pointer to enumerator */ + const char *p_dirname, /* Directory we're searching in */ + const char *p_pattern /* Pattern we're searching for */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * find_next_file() + * + * DESCRIPTION + * Continues a search initialised by find_first_file(). Users should + * call find_next_file() until it returns FALSE, then close_file_find(). + * + * RETURNS + * TRUE <=> next file found, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t find_next_file( + char *p_name, /* Name of file found (output) */ + file_enum_t *p_enum /* Pointer to enumerator */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * close_file_find() + * + * DESCRIPTION + * Close the file search. Free memory, close handles etc. The enumerator + * is ready for another call to find_first_file(). User should always + * call close_file_find() if find_first_file() returns TRUE or resources + * may be leaked. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void close_file_find( + file_enum_t *p_enum /* Pointer to enumerator */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * filecomp() + * + * DESCRIPTION + * Compare files. + * + * RETURNS + * 0 <=> contents of files is the same, != 0 else. + *----------------------------------------------------------------------------*/ + +extern int filecomp( + const char *p_file1, /* Name of first file */ + const char *p_file2 /* Name of second file */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * get_file_image() + * + * DESCRIPTION + * Load file into memory. + * + * RETURNS + * TRUE <=> file i/o successful, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t get_file_image( + file_image_t *p, /* Info on file (output) */ + const char *p_name /* Name of file */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * free_file_image() + * + * DESCRIPTION + * Free up resources allocated to a file image. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void free_file_image( + file_image_t *p /* Info on file (output) */ + ); diff --git a/test/vformat.c b/test/vformat.c new file mode 100644 index 0000000..b4a753d --- /dev/null +++ b/test/vformat.c @@ -0,0 +1,858 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + This software is distributed under the GNU Lesser General Public Licence. + Please read and understand the comments at the top of vf_iface.h before use! + +FILE + $Workfile$ + $Revision: 1.18 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Platform independant test harness for the vformat library functions. This + code runs various tests on the library, results are written to stdout. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vformat.c,v $ + * Revision 1.18 2002/11/16 13:33:18 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.17 2002/11/15 09:14:59 tilda + * IID638823 - Various portability issues. + * + * Revision 1.16 2002/11/14 20:14:25 tilda + * Minot tidy ups to WIN32 versions. + * + * Revision 1.15 2002/11/11 17:23:08 monos + * run testing harness on linux systems + * + * Revision 1.14 2002/11/03 18:56:45 tilda + * Add test functions for VCAL encoding functions. + * + * Revision 1.13 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.12 2002/11/02 09:03:45 tilda + * Start of internationalisation changes. + * + * Revision 1.11 2001/11/18 22:05:57 tilda + * Correct args for vf_get_property(). + * + * Revision 1.10 2001/10/24 20:20:27 tilda + * uit printing when we're done. + * + * Revision 1.9 2001/10/24 18:40:40 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.8 2001/10/24 05:33:59 tilda + * Test harness / file list mods + * + * Revision 1.7 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.6 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.5 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.4 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.3 2001/10/12 19:02:15 tilda + * Moved generic test functions to new file + * + ******************************************************************************/ + +#ifndef NORCSID +static const char vformat_c_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/vformat.c,v 1.18 2002/11/16 13:33:18 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "testsuppt.h" + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define LINELENGTH (76) + +#define MAXBASE64ENC (1000) + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +static void read_cards_from_dir(const char *dirname, const char *p_pattern); +static void test_read_vcard(const char *filename); +static bool_t read_show_status(VF_OBJECT_T **pp_object, const char *p_name); +static bool_t write_show_status(const char *p_name, VF_OBJECT_T *p_object); +static void update_results(bool_t pass, bool_t warning); +static void do_title_line(const char *filename); +static void print_search_results(VF_PROP_T *p_tmp); +static void check_extract_fields(const char *filename, const char *p_array[3]); +static void check_extract_groups(const char *filename, const char *p_group); +static void check_base64_enc(bool_t rdata); +static bool_t encode_decode_check(const char *p_data, uint32_t length); +static void check_vcal_functions(void); +static void get_random_date(VF_ISO8601_PERIOD_T *p_period); +static void get_out_file(char *, const char *, const char *); + +/*============================================================================* + Private Data + *============================================================================*/ + +static int tot_tests = 0; +static int tot_errors = 0; +static int tot_warnings = 0; + +static const char *pp_tel_fields[3] = +{ + VFP_TELEPHONE, + VFP_WORK, + VFP_PREFERRED +}; + + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * main() + * + * DESCRIPTION + * Entry point. + * + * RETURNS + * Hopefully. + *----------------------------------------------------------------------------*/ + +int main(int argc, char **argv) +{ + /* + * simple reading / writing tests. + */ + read_cards_from_dir("tests//spec", "*.vcf"); + read_cards_from_dir("tests//adhoc", "*.vcf"); + read_cards_from_dir("tests//utf-8", "*.vcf"); + + /* + * list access functions. + */ + check_extract_fields("tests//access//access_1.vcf", pp_tel_fields); + check_extract_groups("tests//adhoc//group_7.vcf", "ALPHA"); + + /* + * data format tests. + */ + check_base64_enc(TRUE); + + /* + * VCAL access functions + */ + check_vcal_functions(); + + /* split_phonebook("C:\\Windows\\Desktop\\Whole Phonebook.vcf", "C:\\Temp"); */ + + + /* for automatic testing */ + if (tot_errors) exit (1); + exit (0); +} + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * main() + * + * DESCRIPTION + * Entry point. + * + * RETURNS + * Hopefully. + *----------------------------------------------------------------------------*/ + +void read_cards_from_dir( + const char *p_dirname, + const char *p_pattern + ) +{ + file_enum_t f; + char filename[_MAX_PATH]; + + if (find_first_file(filename, &f, p_dirname, p_pattern)) + { + do + { + test_read_vcard(filename); + } + while (find_next_file(filename, &f)) + ; + + close_file_find(&f); + } +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * test_read_vcard() + * + * DESCRIPTION + * Attempt to read the indicated card. If the read succeeds, then write + * the card out to a new file. Compare the original file with the new + * files - they will be the same if the file was in exactly the format + * produced by this library (line lengths & ends may differ of course as + * well as choice of characters escaped in quoted printable format). + * + * We then read in "our" version of the test file and write it out. This + * time, the output should be the same as the input. Well - for the + * purposes of this test I consider it an error if they differ! + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void test_read_vcard( + const char *filename + ) +{ + VF_OBJECT_T *p_object = NULL; + bool_t warning = FALSE, pass = FALSE; + + do_title_line(filename); + + if (read_show_status(&p_object, filename)) + { + VF_OBJECT_T *p_object_1 = NULL; + char outfile_1[_MAX_PATH]; + char outfile_2[_MAX_PATH]; + + get_out_file(outfile_1, ".out-1", filename); + get_out_file(outfile_2, ".out-2", filename); + + write_show_status("vobject.vcf", p_object); + + write_show_status(outfile_1, p_object); + + if (0 == filecomp(outfile_1, filename)) + { + printf(" OK - no differences after 1st read/write\n"); + } + else + { + printf(" Warning - differences after 1st read/write\n"); + + warning = TRUE; + } + + if (read_show_status(&p_object_1, outfile_1)) + { + write_show_status(outfile_2, p_object_1); + } + + if (0 == filecomp(outfile_2, outfile_1)) + { + printf(" OK - no differences after 2nd read/write\n"); + + pass = TRUE; + } + else + { + printf(" Error - differences after 2nd read/write\n"); + } + + vf_delete_object(p_object, TRUE); + vf_delete_object(p_object_1, TRUE); + } + + update_results(pass, warning); +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * do_title_line() + * + * DESCRIPTION + * Print a title line. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void do_title_line(const char *filename) +{ + char title[LINELENGTH]; + + memset(title, '-', sizeof(title)); + title[sizeof(title) - 1] = '\0'; + memcpy(title + 2, filename, strlen(filename)); + printf("\n%s\n", title); +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * read_show_status() + * + * DESCRIPTION + * Wrapper on vf_read_file() which displays status after the read. + * + * RETURNS + * Same as wrapped vf_read_file(). + *----------------------------------------------------------------------------*/ + +static bool_t read_show_status( + VF_OBJECT_T **pp_object, + const char *p_name + ) +{ + bool_t ret; + + ret = vf_read_file(pp_object, p_name); + + if (ret) + { + printf("Successfully read file '%s'\n", p_name); + } + else + { + printf("Failed to read file '%s'\n", p_name); + } + + return ret; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_show_status() + * + * DESCRIPTION + * Wrapper on vf_write_file() which displays status after the read. + * + * RETURNS + * Same as wrapped vf_read_file(). + *----------------------------------------------------------------------------*/ + +static bool_t write_show_status( + const char *p_name, + VF_OBJECT_T *p_object + ) +{ + bool_t ret; + + ret = vf_write_file(p_name, p_object, TRUE); + + if (ret) + { + printf("Successfully wrote file '%s'\n", p_name); + } + else + { + printf("Failed to wrote file '%s'\n", p_name); + } + + return ret; +} + + + +/*----------------------------------------------------------------------------* + * NAME + * write_show_status() + * + * DESCRIPTION + * Wrapper on vf_write_file() which displays status after the read. + * + * RETURNS + * Same as wrapped vf_read_file(). + *----------------------------------------------------------------------------*/ + +static void update_results( + bool_t pass, + bool_t warning + ) +{ + char buffer[80]; + + tot_tests += 1; + + if (pass) + { + /* OK */ + } + else + { + tot_errors += 1; + } + + if (warning) + { + tot_warnings += 1; + } + + sprintf(buffer, "[%d tests, %d errors, %d warnings]", + tot_tests, tot_errors, tot_warnings); + + printf("%*s\n", LINELENGTH-1, buffer); +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * check_extract_fields() + * + * DESCRIPTION + * Exract fields. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void check_extract_fields( + const char *filename, + const char *p_array[3] + ) +{ + VF_OBJECT_T *p_object = NULL; + bool_t warning = FALSE, pass = FALSE; + + do_title_line(filename); + + if (read_show_status(&p_object, filename)) + { + VF_PROP_T *p_tmp; + + printf(" Looking for {%s}...\n", p_array[0]); + if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], NULL)) + { + print_search_results(p_tmp); + } + + printf(" Looking for {%s, %s}...\n", p_array[0], p_array[1]); + if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[1], NULL)) + { + print_search_results(p_tmp); + } + + printf(" Looking for {%s, %s}...\n", p_array[0], p_array[2]); + if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[2], NULL)) + { + print_search_results(p_tmp); + } + + printf(" Looking for {%s, %s, %s}...\n", p_array[0], p_array[1], p_array[2]); + if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[1], p_array[2], NULL)) + { + print_search_results(p_tmp); + } + + vf_delete_object(p_object, TRUE); + + pass = TRUE; + } + + update_results(pass, warning); +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * extract_groups() + * + * DESCRIPTION + * + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void check_extract_groups( + const char *filename, + const char *p_group + ) +{ + VF_OBJECT_T *p_object = NULL; + bool_t warning = FALSE, pass = FALSE; + + do_title_line(filename); + + if (read_show_status(&p_object, filename)) + { + VF_PROP_T *p_tmp; + + if (vf_get_property(&p_tmp, p_object, VFGP_FIND, p_group, "LOGO", NULL)) + { + print_search_results(p_tmp); + } + + vf_delete_object(p_object, TRUE); + + pass = TRUE; + } + + update_results(pass, warning); +} + + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * print_search_results() + * + * DESCRIPTION + * List the values in each of the current search results. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void print_search_results( + VF_PROP_T *p_tmp /* Pointer to current property */ + ) +{ + do + { + void *ptr; + uint32_t size; + vf_encoding_t enc; + + if (vf_get_prop_value(p_tmp, &ptr, &size, &enc)) + { + switch (enc) + { + case VF_ENC_BASE64: + { + printf(" prop = \"%s\"\n", vf_get_prop_name_string(p_tmp, 0)); + } + break; + + case VF_ENC_7BIT: + case VF_ENC_QUOTEDPRINTABLE: + { + uint16_t i; + + for (i = 0;;i++) + { + const char *p_value = vf_get_prop_value_string(p_tmp, i); + + if (p_value) + { + printf(" field[%d] = \"%s\"\n", i, p_value); + } + else + { + break; + } + } + } + break; + } + } + } + while (vf_get_next_property(&p_tmp)) + ; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * check_base64_enc() + * + * DESCRIPTION + * Check BASE64 encoding. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void check_base64_enc(bool_t rdata) +{ + char buffer[MAXBASE64ENC+1]; + int i, s; + bool_t pass; + + do_title_line("BASE64 encoding"); + + for (s = 1, pass = TRUE;pass && (s < sizeof(buffer));s++) + { + for (i = 0;i < s;i++) + { + buffer[i] = (rdata ? rand() : (i + 1)) % 256; + } + + pass &= encode_decode_check(buffer, s); + + if (pass) + { + printf("encode_decode_check() : OK @ %d bytes\r", s); + } + } + + printf("\n"); + + update_results(pass, 0); +} + + + +/*----------------------------------------------------------------------------* + * NAME + * encode_decode_check() + * + * DESCRIPTION + * Encode & decode chunk of data. Check data consistency. + * + * RETURNS + * TRUE iff encoded / decoded successfully. + *----------------------------------------------------------------------------*/ + +static bool_t encode_decode_check( + const char *p_data, /* Pointer to data */ + uint32_t length /* Length */ + ) +{ + VF_OBJECT_T *p_object; + const char *testfile = "bindata.vcf"; + const char *testprop = "X-BINARY-DATA"; + + bool_t pass = FALSE; + + p_object = vf_create_object("TEST", NULL); + + if (p_object) + { + VF_PROP_T *p_prop; + + if (vf_get_property(&p_prop, p_object, VFGP_GET, NULL, testprop, NULL)) + { + vf_set_prop_value_base64(p_prop, p_data, length, TRUE); + } + + vf_write_file(testfile, p_object, TRUE); + + vf_delete_object(p_object, TRUE); + } + + if (vf_read_file(&p_object, testfile)) + { + VF_PROP_T *p_prop; + + if (vf_get_property(&p_prop, p_object, VFGP_FIND, NULL, testprop, NULL)) + { + const char *p_new_data; + uint32_t new_length; + + p_new_data = vf_get_prop_value_base64(p_prop, &new_length); + + if (p_new_data) + { + if (length == new_length) + { + if (0 == memcmp(p_data, p_new_data, length)) + { + pass = TRUE; + } + else + { + printf("encode_decode_check() : data NOT OK\n"); + } + } + else + { + printf("encode_decode_check() : Length error\n"); + } + } + else + { + printf("encode_decode_check() : No data\n"); + } + } + + vf_delete_object(p_object, TRUE); + } + + return pass; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * check_vcal_functions() + * + * DESCRIPTION + * Check the date encoding functions. This is a non systematic random + * test ehich generates random values, encodes them, decodes them and + * compares the result with the initial value. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void check_vcal_functions(void) +{ + VF_ISO8601_PERIOD_T test_in, test_out; + int i; + bool_t pass; + + do_title_line("VCAL encoding functions"); + + for (i = 0, pass = TRUE;pass && (i < 1000);i++) + { + char sz[256]; + + get_random_date(&test_in); + + vf_period_time_to_string(sz, &test_in); + vf_period_string_to_time(&test_out, sz); + + if (memcmp(&test_in, &test_out, sizeof(VF_ISO8601_PERIOD_T))) + { + pass = FALSE; + } + else + { + printf("check_vcal_functions() : %s \r", sz); + } + } + + printf("\n"); + + update_results(pass, 0); +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * get_random_date() + * + * DESCRIPTION + * Initialise a random VF_ISO8601_PERIOD_T value. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void get_random_date(VF_ISO8601_PERIOD_T *p_period) +{ + p_period->days = rand() % 100; + p_period->hours = rand() % 24; + p_period->minutes = rand() % 60; + p_period->months = rand() % 12; + p_period->seconds = rand() % 60; + p_period->weeks = rand() % 9; + p_period->years = rand() % 20; +} + + + +/*----------------------------------------------------------------------------* + * NAME + * get_out_file() + * + * DESCRIPTION + * Obtain the name of a test output file from a teset input file. The + * outout filename is the input name with the subscript replaced. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void get_out_file( + char *p_outfile, /* Buffer to receive filename */ + const char *p_subscript, /* New subscript */ + const char *p_infile /* Name of source file we're mimicing */ + ) +{ + char *p_found_subscript; + + strcpy(p_outfile, p_infile); + + if (NULL == (p_found_subscript = strstr(p_outfile, "."))) + { + printf("get_out_file() : invalid name (%s) in test files\n", p_outfile); + } + else + { + strcpy(p_found_subscript, p_subscript); + } +} + diff --git a/vf_iface.h b/vf_iface.h new file mode 100644 index 0000000..6627bf5 --- /dev/null +++ b/vf_iface.h @@ -0,0 +1,35 @@ +/****************************************************************************** + + (C) Mathias Palm, 2002 - + + THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + * This file is only an auxiliary for the linux distribution + */ + +#ifndef _VF_IFACE_H_ +#include "iface/vf_iface.h" +#endif diff --git a/vformat/Makefile.am b/vformat/Makefile.am new file mode 100644 index 0000000..325ccb3 --- /dev/null +++ b/vformat/Makefile.am @@ -0,0 +1,2 @@ +include_HEADERS = vf_iface.h + diff --git a/vformat/vf_iface.h b/vformat/vf_iface.h new file mode 100644 index 0000000..8dc1b62 --- /dev/null +++ b/vformat/vf_iface.h @@ -0,0 +1,1269 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +FILE + $Workfile: vf_iface.h $ + $Revision: 1.30 $ + $Author: monos $ + +ORIGINAL AUTHOR + Tilda@users.sourceforge.net <Nick Marley> + +DESCRIPTION + Main include file for the vFormat object library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_iface.h,v $ + * Revision 1.30 2002/12/07 17:25:44 monos + * *** empty log message *** + * + * Revision 1.29 2002/11/24 14:26:22 tilda + * IID484686 - More vcard work. + * + * Revision 1.28 2002/11/17 10:01:02 tilda + * IID484686 - Yet more vCalendar stuff. + * + * Revision 1.27 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.26 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.25 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.24 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.23 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.22 2002/10/08 21:15:56 tilda + * IID619851 - Update comments. + * + * Revision 1.21 2002/02/24 17:10:35 tilda + * Add API for "is modified" functionality. + * + * Revision 1.20 2002/02/16 19:14:36 tilda + * Various mods improving the command line options. + * + * Revision 1.19 2002/01/12 15:55:32 tilda + * Add pragmas for linking. + * + * Revision 1.18 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + * Revision 1.17 2001/12/28 17:23:50 tilda + * Minor mods to VTODO etc. defines. + * + * Revision 1.16 2001/11/16 22:34:49 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.15 2001/11/15 08:55:15 tilda + * Minor reorganisation & add comments where missing. + * + * Revision 1.14 2001/11/14 22:36:56 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.13 2001/11/14 16:04:16 tilda + * Add VFP_ names. + * + * Revision 1.12 2001/11/12 20:24:54 tilda + * Add properties. + * + * Revision 1.11 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.10 2001/11/05 21:08:02 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.9 2001/10/24 18:36:45 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.8 2001/10/24 05:33:16 tilda + * Start work on object create/modify API. + * + * Revision 1.7 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.6 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.5 2001/10/14 16:40:35 tilda + * Initial testing of access functions. + * + * Revision 1.4 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.3 2001/10/10 20:54:34 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef _VF_IFACE_H_ +#define _VF_IFACE_H_ + +#ifndef NORCSID +static const char vf_iface_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/vf_iface.h,v 1.30 2002/12/07 17:25:44 monos Exp $"; +#endif + +/*============================================================================* + Public Includes + *============================================================================*/ + +#include <common/types.h> + +#include <stdarg.h> + +/* c2man (for producing man pages) can't handle some lines in time.h */ + +#ifndef __C2MAN__ +#include <time.h> +#else +#define time_t long int +#endif + +/*============================================================================* + Public defines + *============================================================================*/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Default .DLL build using the symbols maintained by MSDEV. + */ +#if defined(WIN) || defined(WIN32) + #if defined(_USRDLL) + #ifndef VFORMATDECLSPEC + #ifdef VFORMATL_EXPORTS + #define VFORMATDECLSPEC __declspec(dllexport) + #else + #define VFORMATDECLSPEC __declspec(dllimport) + #endif + #endif + #endif +#endif + +#if defined(WIN) || defined(WIN32) + #if !defined(VFORMAT_BUILD) + #if defined(_DEBUG) + #pragma comment(lib, "VFORMATLD.lib") + #else + #pragma comment(lib, "VFORMATL.lib") + #endif + #endif +#endif + + +/* + * Remove VFORMATDECLSPEC if not defined. + */ +#ifndef VFORMATDECLSPEC + #define VFORMATDECLSPEC +#endif + + +/*----------------------------------------------------------------------------* + * PURPOSE + * Definitions of the standard properties. + *----------------------------------------------------------------------------*/ + +#define VFP_AALARM "AALARM" +#define VFP_ADDITIONALNAMES "ADDN" +#define VFP_ADR "ADR" +#define VFP_AGENT "AGENT" +#define VFP_AIFF "AIFF" +#define VFP_AOL "AOL" +#define VFP_APPLELINK "APPLELINK" +#define VFP_ATTACH "ATTACH" +#define VFP_ATTENDEE "ATTENDEE" +#define VFP_ORGANIZER "ORGANIZER" +#define VFP_OWNER "OWNER" +#define VFP_DELEGATE "DELEGATE" +#define VFP_ACCEPTED "ACCEPTED" +#define VFP_NEEDSACTION "NEEDS ACTION" +#define VFP_SENT "SENT" +#define VFP_TENTATIVE "TENTATIVE" +#define VFP_CONFIRMED "CONFIRMED" +#define VFP_DECLINED "DECLINED" +#define VFP_COMPLETED "COMPLETED" +#define VFP_DELEGATED "DELEGATED" +#define VFP_CATERING "CATERING" +#define VFP_COMPUTERPROJECTOR "COMPUTER PROJECTOR" +#define VFP_EASEL "EASEL" +#define VFP_OVERHEADPROJECTOR "OVERHEAD PROJECTOR" +#define VFP_SPEAKERPHONE "SPEAKER PHONE" +#define VFP_TABLE "TABLE" +#define VFP_TV "TV" +#define VFP_VCR "VCR" +#define VFP_VIDEOPHONE "VIDEO PHONE" +#define VFP_VEHICLE "VEHICLE" +#define VFP_ATTMAIL "ATTMAIL" +#define VFP_AUDIOCONTENT "AUDIOCONTENT" +#define VFP_AVI "AVI" +#define VFP_BBS "BBS" +#define VFP_BIRTHDATE "BDAY" +#define VFP_BMP "BMP" +#define VFP_BODY "BODY" +#define VFP_BUSINESSROLE "ROLE" +#define VFP_CAPTION "CAP" +#define VFP_CAR "CAR" +#define VFP_CATEGORIES "CATEGORIES" +#define VFP_CELLULAR "CELL" +#define VFP_CGM "CGM" +#define VFP_CHARSET "CHARSET" +#define VFP_CID "CID" +#define VFP_CIS "CIS" +#define VFP_CITY "L" +#define VFP_CLASS "CLASS" +#define VFP_COMMENT "NOTE" +#define VFP_COMPLETED "COMPLETED" +#define VFP_CONTENTID "CONTENT-ID" +#define VFP_COUNTRYNAME "C" +#define VFP_DALARM "DALARM" +#define VFP_DATASIZE "DATASIZE" +#define VFP_DAYLIGHT "DAYLIGHT" +#define VFP_DCREATED "DCREATED" +#define VFP_DELIVERYLABEL "LABEL" +#define VFP_DESCRIPTION "DESCRIPTION" +#define VFP_DIB "DIB" +#define VFP_DISPLAYSTRING "DISPLAYSTRING" +#define VFP_DOMESTIC "DOM" +#define VFP_DTEND "DTEND" +#define VFP_DTSTART "DTSTART" +#define VFP_DUE "DUE" +#define VFP_EMAILADDRESS "EMAIL" +#define VFP_ENCODING "ENCODING" +#define VFP_EWORLD "EWORLD" +#define VFP_EXNUM "EXNUM" +#define VFP_EXPDATE "EXDATE" +#define VFP_EXPECT "EXPECT" +#define VFP_EXTADDRESS "EXT ADD" +#define VFP_FAMILYNAME "F" +#define VFP_FAX "FAX" +#define VFP_FULLNAME "FN" +#define VFP_GEO "GEO" +#define VFP_GEOLOCATION "GEO" +#define VFP_GIF "GIF" +#define VFP_GIVENNAME "G" +#define VFP_GROUPING "GROUPING" +#define VFP_HOME "HOME" +#define VFP_IBMMAIL "IBMMAIL" +#define VFP_INLINE "INLINE" +#define VFP_INTERNATIONAL "INTL" +#define VFP_INTERNET "INTERNET" +#define VFP_ISDN "ISDN" +#define VFP_JPEG "JPEG" +#define VFP_LANGUAGE "LANG" +#define VFP_LASTMODIFIED "LAST-MODIFIED" +#define VFP_LASTREVISED "REV" +#define VFP_LOCATION "LOCATION" +#define VFP_LOGO "LOGO" +#define VFP_MAILER "MAILER" +#define VFP_MALARM "MALARM" +#define VFP_MCIMAIL "MCIMAIL" +#define VFP_MESSAGE "MSG" +#define VFP_MET "MET" +#define VFP_MODEM "MODEM" +#define VFP_MPEG2 "MPEG2" +#define VFP_MPEG "MPEG" +#define VFP_MSN "MSN" +#define VFP_NAMEPREFIXES "NPRE" +#define VFP_NAME "N" +#define VFP_NAMESUFFIXES "NSUF" +#define VFP_NOTE "NOTE" +#define VFP_ORGNAME "ORGNAME" +#define VFP_ORG "ORG" +#define VFP_ORGUNIT2 "OUN2" +#define VFP_ORGUNIT3 "OUN3" +#define VFP_ORGUNIT4 "OUN4" +#define VFP_ORGUNIT "OUN" +#define VFP_PAGER "PAGER" +#define VFP_PALARM "PALARM" +#define VFP_PARCEL "PARCEL" +#define VFP_PART "PART" +#define VFP_PCM "PCM" +#define VFP_PDF "PDF" +#define VFP_PGP "PGP" +#define VFP_PHOTO "PHOTO" +#define VFP_PROPTYPE "TYPE" +#define VFP_PICT "PICT" +#define VFP_PMB "PMB" +#define VFP_POSTALBOX "BOX" +#define VFP_POSTALCODE "PC" +#define VFP_POSTAL "POSTAL" +#define VFP_POWERSHARE "POWERSHARE" +#define VFP_PREFERRED "PREF" +#define VFP_PRIORITY "PRIORITY" +#define VFP_PROCEDURENAME "PROCEDURENAME" +#define VFP_PRODID "PRODID" +#define VFP_PRODIGY "PRODIGY" +#define VFP_SOUND "SOUND" +#define VFP_PS "PS" +#define VFP_PUBLICKEY "KEY" +#define VFP_QP "QP" +#define VFP_QUICKTIME "QTIME" +#define VFP_RDATE "RDATE" +#define VFP_REGION "R" +#define VFP_RELATEDTO "RELATED-TO" +#define VFP_REPEATCOUNT "REPEATCOUNT" +#define VFP_RESOURCES "RESOURCES" +#define VFP_RNUM "RNUM" +#define VFP_ROLE "ROLE" +#define VFP_RRULE "RRULE" +#define VFP_RSVP "RSVP" +#define VFP_RUNTIME "RUNTIME" +#define VFP_SEQUENCE "SEQUENCE" +#define VFP_SNOOZETIME "SNOOZETIME" +#define VFP_START "START" +#define VFP_STATUS "STATUS" +#define VFP_STREETADDRESS "STREET" +#define VFP_SUBTYPE "SUBTYPE" +#define VFP_SUMMARY "SUMMARY" +#define VFP_TELEPHONE "TEL" +#define VFP_TIFF "TIFF" +#define VFP_TIMEZONE "TZ" +#define VFP_TITLE "TITLE" +#define VFP_TLX "TLX" +#define VFP_TRANSP "TRANSP" +#define VFP_UNIQUESTRING "UID" +#define VFP_URL "URL" +#define VFP_URLVALUE "URLVAL" +#define VFP_VALUE "VALUE" +#define VFP_VERSION "VERSION" +#define VFP_VIDEO "VIDEO" +#define VFP_VOICE "VOICE" +#define VFP_WAVE "WAVE" +#define VFP_WMF "WMF" +#define VFP_WORK "WORK" +#define VFP_X400 "X400" +#define VFP_X509 "X509" +#define VFP_XRULE "XRULE" + +#define VFP_UTF8 "UTF-8" + +#define VFP_PRONUNCIATION VFP_SOUND /* ??? */ + +/* + * Property tokesn indicating encoding. + */ +#define VFP_7BIT "7BIT" +#define VFP_8BIT "8BIT" +#define VFP_BASE64 "BASE64" +#define VFP_QUOTEDPRINTABLE "QUOTED-PRINTABLE" + +/* + * Names for the "begin" token. + */ +#define VF_NAME_VCALENDAR "VCALENDAR" +#define VF_NAME_VCARD "VCARD" +#define VF_NAME_VNOTE "VNOTE" +#define VF_NAME_VEVENT "VEVENT" +#define VF_NAME_VTODO "VTODO" + + +/* + * Special token that matches any when searching. + */ +#define VFP_ANY "*" + +/* + * Indexes for compound name properties (the "N" property). + */ +#define VFP_NAME_FAMILY (0) +#define VFP_NAME_GIVEN (1) +#define VFP_NAME_MIDDLE (2) +#define VFP_NAME_TITLE (3) + +/* + * Indexes for compound address properties (the "ADR" property). + */ +#define VFP_ADR_POBOX (0) +#define VFP_ADR_EXTENDED (1) +#define VFP_ADR_STREET (2) +#define VFP_ADR_CITY (3) +#define VFP_ADR_REGION (4) +#define VFP_ADR_POSTCODE (5) +#define VFP_ADR_COUNTRY (6) + +/* + * Indexes for compound organisation properties (the "ORG" property) + */ +#define VFP_ORG_NAME (0) +#define VFP_ORG_DIVISION (1) + +/* + * Type declaring macro. + */ +#define VF_DECLARE_TYPE(x) typedef struct _vf_##x { uint8_t _; } x; + +/*============================================================================* + Public Types + *============================================================================*/ + +/* + * Type representing "parser" - an object used to parse VOBJECTS. + */ +VF_DECLARE_TYPE(VF_PARSER_T) + +/* + * Type representing an "object" - objects are collections of properties. + */ +VF_DECLARE_TYPE(VF_OBJECT_T) + +/* + * Type representing a "property" - properties associate a name & a value. + */ +VF_DECLARE_TYPE(VF_PROP_T) + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VF_ISO8601_PERIOD_T is used to encapsulate an ISO time 'period'. + *----------------------------------------------------------------------------*/ + +typedef struct VF_ISO8601_PERIOD_T +{ + uint32_t years; + uint32_t months; + uint32_t weeks; + uint32_t days; + uint32_t hours; + uint32_t minutes; + uint32_t seconds; +} +VF_ISO8601_PERIOD_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_encoding_t enumerates the supported encodings (formats) of a + * vformat object property. Each "value" has a field of this type. + *----------------------------------------------------------------------------*/ + +typedef uint8_t vf_encoding_t; + +#define VF_ENC_UNKNOWN ((vf_encoding_t)(0)) +#define VF_ENC_7BIT ((vf_encoding_t)(1)) +#define VF_ENC_8BIT ((vf_encoding_t)(2)) +#define VF_ENC_BASE64 ((vf_encoding_t)(3)) +#define VF_ENC_QUOTEDPRINTABLE ((vf_encoding_t)(4)) +#define VF_ENC_VOBJECT ((vf_encoding_t)(5)) + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_get_t controls the operation of vf_get_property() (qv). Controls + * how far the search algorithm is prepared to go in order to return a + * property ready for modification. + *----------------------------------------------------------------------------*/ + +typedef uint16_t vf_get_t; + +#define VFGP_FIND ((vf_get_t)(0x0001)) /* Search for property */ +#define VFGP_APPEND ((vf_get_t)(0x0002)) /* Append property, no search */ +#define VFGP_GET ((vf_get_t)(0x0003)) /* Find & append if not present */ + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_search_flags_t is used to describe how string matching is performed + * when searching for properties, qualifiers, values etc. + *----------------------------------------------------------------------------*/ + +typedef uint32_t vf_search_flags_t; + +/*============================================================================* + Public Functions + *============================================================================*/ + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_init() + * + * DESCRIPTION + * Allocate and initialise a parser. To parse a VCARD (or any vObject) + * a user allocates a parser, pushes data through it using vf_parse_text() + * and finally calls vf_parse_end(): + * + * VF_PARSER_T *p_parser; + * + * if (vf_parse_init(&p_parser, pp_object)) + * { + * do + * { + * char buffer[...]; + * int numchars; + * + * numchars = get_chars_from_somewhere(buffer, ...); + * + * ret = vf_parse_text(p_parser, buffer, numchars); + * } + * while (ret && (0 < charsread)) + * ; + * + * if (!vf_parse_end(p_parser)) + * { + * ret = FALSE; + * } + * } + * + * A parser allocated by vf_parse_init(), must be deallocated by calling + * vf_parse_end() whether or not parsing succeeds. Also, parsing may not + * be complete (ie. values may be held buffered and not evaluated fully + * or assigned to a VF_OBJECT_T) untill the final call to vf_parse_end() + * => after a vf_parse_init() you _must_ vf_parse_end(). + * + * RETURNS + * TRUE iff parser allocated successfully. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_init( + VF_PARSER_T **pp_parser, /* Ptr to allocated parser */ + VF_OBJECT_T **pp_object /* The object we're parsing into */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_text() + * + * DESCRIPTION + * Parse indicated text into the object associated with the VPARSE_T. + * + * See notes for vf_parse_init(). + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_text( + VF_PARSER_T *p_parse, /* The parser */ + char *p_chars, /* New characters to parse into object */ + int numchars /* Number of new characters */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_end() + * + * DESCRIPTION + * Ensure parse completion, release memory associated with the parser. + * + * See notes for vf_parse_init(). + * + * RETURNS + * TRUE <=> parse complete with no error. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_end( + VF_PARSER_T *p_parse /* The parser */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_read_file() + * + * DESCRIPTION + * Reads indicated VOBJECT_T file. + * + * RETURNS + * TRUE <=> read OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_read_file( + VF_OBJECT_T **pp_object, /* Pointer to output object */ + const char *p_name /* Name of file to read */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_write_file() + * + * DESCRIPTION + * Write indicated vobject to file. For lists of objects (eg. read from + * a phonebook) the write_all parameter allows the caller to control if + * the library writes the entire list or just the head item. + * + * RETURNS + * TRUE <=> written OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_write_file( + const char *p_name, /* Outpt filename */ + VF_OBJECT_T *p_object, /* The object to write */ + bool_t write_all /* Should write p_next as well? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_object() + * + * DESCRIPTION + * Find "next" vobject. Typically called after a call to vf_read_file() + * which may well read a list of objects from a file for example: + * + * if (vf_read_file(&p_object, p_filename)) + * { + * do + * { + * ... + * } + * while (vf_get_next_object(&p_object)) + * ; + * } + * + * The value of *pp_object is updated by the call if it returns TRUE. + * + * RETURNS + * TRUE iff found (ie. there is a "next" object). + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_next_object( + VF_OBJECT_T **pp_object /* Ptr to pointer to current object */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_create_object() + * + * DESCRIPTION + * Creates an empty vformat object. + * + * RETURNS + * Ptr to object if created else NULL. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC VF_OBJECT_T *vf_create_object( + const char *p_type, /* Type of object to create */ + VF_OBJECT_T *p_parent /* Parent object if any */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_object_type() + * + * DESCRIPTION + * Return the type string identifying the indicated vformat object, + * the string after the 'BEGIN' mark so 'VCARD' or 'VNOTE' etc. + * + * RETURNS + * Ptr to string. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const char *vf_get_object_type( + VF_OBJECT_T *p_object /* Object to locate type of */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property() + * + * DESCRIPTION + * Basic searching function locating elements of the VOBJECT by qualified + * name. The function is a varargs function (like sprintf) and the list + * of arguments must be NULL terminated (hence the appearance of the + * p_qualifier argument in the arglist). Valid calls might be: + * + * vf_get_property(&p_out, p_object, VFGP_FIND, NULL, "N", NULL); + * - find and return "N" properties. If there are none, return FALSE. + * + * vf_get_property(&p_out, p_object, VFGP_FIND, NULL, "TEL", "WORK", NULL); + * - find and return "TEL" entries qualified by the "work" attribute + * (ie. work phone numbers). If there are none, return FALSE. + * + * vf_get_property(&p_out, p_object, VFGP_GET, NULL, "TEL", "WORK", NULL); + * - find and return work phone number. The entry is automatically + * added if not pre-existing. + * + * vf_get_property(&p_out, p_object, VFGP_GET, NULL, "TEL", "WORK", NULL); + * - find and return work phone numbers in the group identifier by the "ME" + * identifier. The entry is automatically added if not pre-existing. + * + * vf_get_property(&p_out, p_object, VFGP_FIND, "ME", "*", NULL); + * - effectively enumerates all entries in the "ME" group. + * + * A pointer to the first property matching the search criteria is returned + * via the pp_prop argument. The search actually locates all such matches + * and pointer to subsequent entries (if there are >1) may be found by + * calling the vf_get_next_property() function. + * + * The tags may occur in any order _except_ that the p_name must be first. + * + * Note that the VF_PROP_T returned by pp_prop is an opaque type and the + * functions vf_get_prop_xxxx() etc. must be used to locate real "values". + * + * Cached search results (the list enumerated by subsequent calls to the + * vf_get_next_property() function) are maintained through the use of a + * a single internal pointer therefore this method is not thread safe. + * + * RETURNS + * TRUE iff found/added successfully. Ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_property( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to add to */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + ... /* Subequent qualifiers */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property_ex() + * + * DESCRIPTION + * The grunt behind vf_get_property(). Manages the search as described + * vf_get_property() but takes the list of arguments as a va_list. + * This function should be used when writing higher layer functions + * which take varargs (eg. DDX functions). + * + * RETURNS + * TRUE iff found/added successfully. ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_property_ex( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to search */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + va_list args /* Argument list */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_property() + * + * DESCRIPTION + * Find the next property given the current search critera. User + * calls vf_get_property() to locate first in a bunch of properties + * and can iterate over the rest by calling vf_get_next_property(). + * + * RETURNS + * TRUE iff found, FALSE else. *pp_prop points to the nex property. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_next_property( + VF_PROP_T **pp_prop /* Output pointer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value() + * + * DESCRIPTION + * Get hold of raw fields associated with the property. These are of + * various types: + * + * VF_ENC_VOBJECT + * - *pp_value = pointer to contained VF_OBJECT_T which can be + * passed back to any of the object manipulation functions. + * + * VF_ENC_7BIT, VF_ENC_QUOTEDPRINTABLE + * - *pp_value = ptr to array of char*, *p_size = number of elts. + * + * VF_ENC_8BIT, VF_BASE64 + * - *pp_value = ptr to bytes, *p_size = number of bytes + * + * RETURNS + * TRUE <=> encoding is valid, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_prop_value( + VF_PROP_T *p_prop, /* The property */ + void **pp_value, /* Pointer value */ + uint32_t *p_size, /* Integer value */ + vf_encoding_t *p_encoding /* Type of return values */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value() + * + * DESCRIPTION + * Set values associated with a property. + * + * Passing a value of encoding not the same as the current property + * encoding will cause the property contents to be freed prior to + * setting the indicated value. + * + * RETURNS + * TRUE <=> re-allocation success & encoding correct, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value( + VF_PROP_T *p_prop, /* The property */ + void *p_value, /* Pointer to the data */ + uint32_t n_param, /* Data size or index */ + vf_encoding_t encoding, /* Encoding in use */ + bool_t copy /* Copy the data? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_string() + * + * DESCRIPTION + * Obtain string pointer value from VF_PROP_T. For example a property + * may be defined as: + * + * THING;THIS=STUFF;WITH-QUALIFIERS:fred-fred-fred;gogogo;baabaabaa + * + * A call to vf_get_prop_value_string() specifying n_string=1 will + * return a pointer to the gogogo value. + * + * Return NULL if out of range request, ie. n_string=3 for N:0;1;2 + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC char *vf_get_prop_value_string( + VF_PROP_T *p_prop, /* Property to locate string from */ + uint32_t n_string /* Index to string requred */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name_string() + * + * DESCRIPTION + * Get n'th name string. For example a property may be defined as: + * + * THING;THIS=STUFF;WITH-QUALIFIERS:fred-fred-fred;gogogo;baabaabaa + * + * A call to vf_get_prop_name_string() specifying n_string=2 will + * return a pointer to the WITH-QUALIFIERS value. + * + * Return NULL if out of range request, ie. n_string=4 for X;A;B;C:foo + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC char *vf_get_prop_name_string( + VF_PROP_T *p_prop, /* Property to locate string from */ + uint32_t n_string /* Index to string requred */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_name_string() + * + * DESCRIPTION + * Set n'th name string. + * + * RETURNS + * TRUE iff allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_name_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name() + * + * DESCRIPTION + * Build the property name string in the indicated buffer. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_get_prop_name( + VF_PROP_T *p_prop, /* The property */ + char *p_buffer, /* The buffer */ + uint32_t bufsize /* Size of the buffer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_object() + * + * DESCRIPTION + * Obtain object pointer value from VF_PROP_T. + * + * RETURNS + * Pointer to vobject value (or NULL if not found). + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC VF_OBJECT_T *vf_get_prop_value_object( + VF_PROP_T *p_prop /* Property to locate object from */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_object() + * + * DESCRIPTION + * Set the value of the indicated property to be a VOBJECT. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_base64() + * + * DESCRIPTION + * Get a BASE64 property. Returns ptr, passes length via parameter. + * + * RETURNS + * Ptr to data. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const uint8_t *vf_get_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t *p_length /* Length of the binary data */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_property_from_file() + * + * DESCRIPTION + * Loads the indicated file into memory and sets the indicated property. + * + * RETURNS + * TRUE iff succeded, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_property_from_file( + VF_PROP_T *p_prop, /* The property */ + vf_encoding_t encoding, /* Encoding to use */ + const char *p_filename /* Source filename */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_delete_object() + * + * DESCRIPTION + * Cleans up the memory used by the indicated vformat object. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_delete_object( + VF_OBJECT_T *p_object, /* The object to delete */ + bool_t all /* Delete all subsequent objects? */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_prop() + * + * DESCRIPTION + * Deletes indicated property from the indicated object. Deletes prop + * contents if dc is set. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_delete_prop( + VF_OBJECT_T *p_object, /* The object we're deleting from */ + VF_PROP_T *p_prop, /* The property we're removing */ + bool_t dc /* Should property contents be deleted? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_find_prop_qual_index() + * + * DESCRIPTION + * Locate property qualifier given either an array of possible values + * or a single token that is either present or absent. For example + * if we have a property: + * + * NAME;THIRD;TIME;LUCKY:VALUE1;VALUE2;VALUE3 + * + * Then there are two possible searches. + * + * Firstly we can look for the property qualifier which can take values + * from the array { "FIRST", "SECOND", THIRD" } in which case the array + * is passed as pp_possible_values and the function returns with the + * values *p_found_value_index=2, p_qualifier_index=1 + * + * Secondly we can look for the token with value "TIME" in which case + * p_token is set to "TIME" and the function returns *p_qualifier_index=2. + * + * RETURNS + * TRUE iff found, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_find_prop_qual_index( + VF_PROP_T *p_prop, /* The property we're querying */ + uint32_t *p_qualifier_index, /* Ptr to output name index */ + uint32_t *p_found_value_index, /* Ptr to output index in array */ + const char **pp_possible_values, /* Array of possible values */ + const char *p_token, /* Token searched for */ + vf_search_flags_t match /* String comparison flags */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_is_modified() + * + * DESCRIPTION + * Fetch status of modified flag. + * + * RETURNS + * TRUE iff modified since list read/write. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_is_modified( + VF_OBJECT_T *p_object /* The object */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * vf_find_charset() + * + * DESCRIPTION + * Locate the CHARSET property which indicates the character encoding + * in use - which indicates how the octet stream encoded in the VCARD + * is to be decoded into characters. + * + * RETURNS + * Pointer to character encoding name eg. "UTF-8". + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const char *vf_find_charset( + VF_PROP_T *p_prop /* The property we're querying */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_date_string_to_time() + * + * DESCRIPTION + * Convert calendar string to absolute time. The basic formats are + * 19960401, 19960401T073000Z + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_date_string_to_time( + uint32_t *p_time, /* Output time value */ + const char *p_string /* Input string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_string_to_time() + * + * DESCRIPTION + * Convert period definition string to time value. The format is + * P[aaaY][bbbM][cccW][dddD]T[eeeH][fffM][gggS] where 'aaa' is a + * number of years, bbb months etc. + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_period_string_to_time( + VF_ISO8601_PERIOD_T *p_period, /* Output time value */ + const char *p_string /* Input string */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_time_to_string() + * + * DESCRIPTION + * Convert a VF_ISO8601_PERIOD_T to a string. + * + * RETURNS + * Number of characters written. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC uint32_t vf_period_time_to_string( + char *p_string, /* Output string */ + const VF_ISO8601_PERIOD_T *p_period /* Input period value */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_time() + * + * DESCRIPTION + * Set a time_t value into a VF property. + * + * RETURNS + * TRUE iff property added & set OK. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're encoding to */ + const time_t t_value /* Time value */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_time() + * + * DESCRIPTION + * Fetch a time_t value from a VF property. + * + * RETURNS + * TRUE iff foudn & converted OK. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're decoding */ + time_t *p_t_value /* Pointer to output time value */ + ); + + +#if defined(__cplusplus) +} +#endif + +/*============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_IFACE_H_*/ |