Compare commits

...

No commits in common. "master" and "gh-pages" have entirely different histories.

309 changed files with 385 additions and 112895 deletions

View file

@ -1,149 +0,0 @@
# Generated from CLion Inspection settings
#bugprone-reserved-identifier,
---
Checks: '-*,
-deprecated-non-prototype
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-branch-clone,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-fold-init-type,
bugprone-forward-declaration-namespace,
bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase,
bugprone-incorrect-roundings,
bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-no-escape,
bugprone-not-null-terminated-result,
bugprone-parent-virtual-call,
bugprone-posix-return,
bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-spuriously-wake-up-functions,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-suspicious-memory-comparison,
bugprone-suspicious-realloc-usage,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-self-assignment,
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-virtual-near-miss,
cert-dcl21-cpp,
cert-dcl58-cpp,
cert-err34-c,
cert-err52-cpp,
cert-err60-cpp,
cert-flp30-c,
cert-msc50-cpp,
cert-msc51-cpp,
cert-str34-c,
cppcoreguidelines-interfaces-global-init,
cppcoreguidelines-narrowing-conversions,
cppcoreguidelines-pro-type-member-init,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-slicing,
google-default-arguments,
google-explicit-constructor,
google-runtime-operator,
hicpp-exception-baseclass,
hicpp-multiway-paths-covered,
misc-misplaced-const,
misc-new-delete-overloads,
misc-no-recursion,
misc-non-copyable-objects,
misc-throw-by-value-catch-by-reference,
misc-unconventional-assign-operator,
misc-uniqueptr-reset-release,
modernize-avoid-bind,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-make-shared,
modernize-make-unique,
modernize-pass-by-value,
modernize-raw-string-literal,
modernize-redundant-void-arg,
modernize-replace-auto-ptr,
modernize-replace-disallow-copy-and-assign-macro,
modernize-replace-random-shuffle,
modernize-return-braced-init-list,
modernize-shrink-to-fit,
modernize-unary-static-assert,
modernize-use-auto,
modernize-use-bool-literals,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-noexcept,
modernize-use-nullptr,
modernize-use-override,
modernize-use-transparent-functors,
modernize-use-uncaught-exceptions,
mpi-buffer-deref,
mpi-type-mismatch,
openmp-use-default-none,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-string-concatenation,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-noexcept-move-constructor,
performance-trivially-destructible,
performance-type-promotion-in-math-fn,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
portability-simd-intrinsics,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-convert-member-functions-to-static,
readability-delete-null-pointer,
readability-deleted-default,
readability-inconsistent-declaration-parameter-name,
readability-make-member-function-const,
readability-misleading-indentation,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-redundant-control-flow,
readability-redundant-declaration,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-redundant-string-init,
readability-simplify-subscript-expr,
readability-static-accessed-through-instance,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
readability-uniqueptr-delete-release,
readability-use-anyofallof'

View file

@ -1,30 +0,0 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
# Ignore diffs/patches
[*.{diff,patch}]
end_of_line = unset
insert_final_newline = unset
trim_trailing_whitespace = unset
indent_size = unset
[*.c]
ident_style = tab
ident_size = 8
[{Makefile,**.mk}]
# Use tabs for indentation (Makefiles require tabs)
indent_style = tab
ident_size = 4
[*.md]
max_line_length = off
trim_trailing_whitespace = false

6
.envrc
View file

@ -1,6 +0,0 @@
export DBSQL_VERSION="$(sh -c '. ./dist/RELEASE; echo $DBSQL_VERSION')"
export DBSQL_VERSION_STRING="$(sh -c '. ./dist/RELEASE; echo $DBSQL_VERSION_STRING')"
#dotenv
watch_file devShell.nix shell.nix flake.nix
use flake || use nix

13
.gitignore vendored
View file

@ -1,13 +0,0 @@
build_unix/**
*~
TAGS
tags
.direnv/
.idea/
dist/autom4te.cache/
dist/config.hin
dist/configure
dist/config.log
src/py/setup.py
test/scr050/Makefile
result-bin

674
LICENSE
View file

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, 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
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU 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
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state 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 program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View file

@ -1,108 +0,0 @@
FLOSS License Exception v2.0
20 October 2007
The DBSQL Exception for Free/Libre and Open Source Software-only Applications
using DBSQL libraries and related resources (the "FLOSS Exception").
Exception Intent
We want specified Free/Libre and Open Source Software ("FLOSS") applications
to be able to use specified GPL-licensed DBSQL client libraries (the "Program")
despite the fact that not all FLOSS licenses are compatible with version 3 of
the GNU General Public License (the "GPL").
Legal Terms and Conditions
As a special exception to the terms and conditions of version 3 or later of
the GPL you are free to distribute a Derivative Work that is formed entirely
from the Program and one or more works (each, a "FLOSS Work") licensed under
one or more of the licenses listed below in section 1, as long as:
1. You obey the GPL in all respects for the Program and the Derivative
Work, except for identifiable sections of the Derivative Work which
are not derived from the Program, and which can reasonably be considered
independent and separate works in themselves,
2. All identifiable sections of the Derivative Work which are not derived
from the Program, and which can reasonably be considered independent and
separate works in themselves,
1. are distributed subject to one of the FLOSS licenses listed below,
and
2. the object code or executable form of those sections are
accompanied by the complete corresponding machine-readable source
code for those sections on the same medium and under the same
FLOSS license as the corresponding object code or executable forms
of those sections, and
3. any works which are aggregated with the Program or with a
Derivative Work on a volume of a storage or distribution medium in
accordance with the GPL, can reasonably be considered independent
and separate works in themselves which are not derivatives of
either the Program, a Derivative Work or a FLOSS Work.
If the above conditions are not met, then the Program may only be copied,
modified, distributed or used under the terms and conditions of the GPL or
another valid licensing option from The DBSQL Group, Inc.
1. FLOSS License List
License name Version(s)/Copyright Date
-----------------------------------------------------|-------------------------
Academic Free License | 2.0
Apache Software License | 1.0/1.1/2.0 or later
Apple Public Source License | 2.0
Artistic license | From Perl 5.8.0
BSD license | "July 22 1999"
Common Development and Distribution License (CDDL) | 1.0
Common Public License | 1.0
GNU Library or "Lesser" General Public License (LGPL)| 2.0/2.1/3.0
Jabber Open Source License | 1.0
MIT License (As listed in file MIT-License.txt) | -
Microsoft Public License (Ms-PL) | 2007
Microsoft Reciprocal License (Ms-RL) | 2007
Mozilla Public License (MPL) | 1.0/1.1
Open Software License | 2.0
OpenSSL license (with original SSLeay license) | "2003" ("1998")
PHP License | 3.0
Python license (CNRI Python License) | -
Python Software Foundation License | 2.1.1
Sleepycat License | "1999"
University of Illinois/NCSA Open Source License | -
W3C License | "2001"
X11 License | "2001"
Zlib/libpng License | -
Zope Public License | 2.0
Due to the many variants of some of the above licenses, we require that any
version follow the 2003 version of the Free Software Foundation's Free
Software Definition (http://www.gnu.org/philosophy/free-sw.html) or version
1.9 of the Open Source Definition by the Open Source Initiative
(http://www.opensource.org/docs/definition.php).
2. Definitions
1. Terms used, but not defined, herein shall have the meaning
provided in the GPL.
2. Derivative Work means a derivative work under copyright law.
3. Applicability
This FLOSS Exception applies to all Programs that contain a notice placed by
The DBSQL Group, Inc. saying that the Program may be distributed under the
terms of this FLOSS Exception. If you create or distribute a work which is a
Derivative Work of both the Program and any other work licensed under the GPL,
then this FLOSS Exception is not available for that work; thus, you must
remove the FLOSS Exception notice from that work and comply with the GPL in
all respects, including by retaining all GPL notices. You may choose to
redistribute a copy of the Program exclusively under the terms of the GPL by
removing the FLOSS Exception notice from that copy of the Program, provided
that the copy has never been modified by you or any third party.
Appendix A. Qualified Libraries and
The following is a a non-exhaustive list of libraries and packages which are
covered by the FLOSS License Exception. Please note that appendix is merely
provided as an additional service to specific FLOSS projects who wish to
simplify licensing information for their users. Compliance with one of the
licenses noted under the "FLOSS license list" section remains a prerequisite.
Package name | Qualifying License | Version
------------------------------|--------------------------|---------------------
Apache Portable Runtime (APR) | Apache Software License | 2.0 or later

46
README
View file

@ -1,46 +0,0 @@
DBSQL 0.4.0: (May 8, 2024)
This is version 0.4.0 of DBSQL.
To view the release and installation documentation, load the distribution
file docs/index.html into your web browser.
This work started from the SQLite project (found on the web at
http://www.sqlite.org/). SQLite and all contributions to the SQLite
project have been placed in the public domain by its author, Dr. Richard Hipp.
There was no assertion of copyright at all on the code I used as a starting
point for my work. In fact there are statements that explicitly disclaim
copyright. I am asserting copyright on this work, DBSQL. I believe
that if you examine the extent to which I've changed, updated, and
modified the SQLite code you'll respect my copyright assertion. This
is a new product, heavily inspired by another.
The goal for DBSQL is to provide a small SQL92 relational database layer
on top of the Berkeley DB database. Berkeley DB is copyright Oracle
Corporation (formerly Sleepycat Software, acquired in Feb 2006) and
licensed under the Sleepycat Public License. That license is compatible
with the GPL for open source use. Recognize that you, as someone using
DBSQL, will need to review the Sleepycat License and the GPL before you
use and redistribute your incorporating work. It is your responsibility
to comply with those licenses as I am in my work on DBSQL itself. My
motivation on a personal level is quite simple, I am in product management
these days and not in the code itself. I believe that product managers
should be engineers at heart with an ability to understand business,
politics, and software sales and support. This is my playground to keep
my engineering skills sharp enough to speak fluent geek. As a former
engineer at Sleepycat I understand and value the Berkeley DB programming
infrasture, design, and methodologies and I have liberally copied and
reused them in this project to improve SQLite in ways that I hope will
be of value to open source users out there. I did this because I see the
value of SQLite to its userbase, it is a perfect example of the 80/20
rule and the KISS method and I admire those qualities in software. My
hope is that the Berkeley DB database engine will provide some significant
features that SQLite cannot such as replication for high availability
while remaining small enough to live comfortably inside applications,
services, and devices.
Information and resources pertaining to DBSQL can be found at dbsql.org.
Commercial licenses without the restrictions found in the GPL can be
purchased for this product. See http://dbsql.org/wiki/CommercialUse

78
TODO
View file

@ -1,78 +0,0 @@
* Rename dbsql_strerror to dbsql_strerr
* Fix logic issue in query processing
tests/smoke2.sql produces incorrect joins
* Check all DB API calls
Make sure a) we check return codes for for all calls into DB and
that b) when there is an error we output it only when configured
to be verbose and c) then return the proper DBSQL error indicating
what went wrong at a higher level.
* Review all reused DB code
Make sure that we're up to date with the latest in DB. Things such
as hashing, etc.
* Find printf/fprintf calls which print error messages
The library should never print messages unless configured to be
verbose.
* tests/
Fix testing infrastructure.
- api.c/__os_sleep()
This is now static in DB's code, so to hack the compile I
commented out the use of __os_sleep() in api.c
- test/scr026
This test has not been updated to check for DBSQL API calls
rather than DB API calls. Review and fix it.
- test/scr030
Update this test to match the configure script. Augment it so
that as the configure script changes the script reports options
not tested.
- A few scr??? < 050
Some of these tests examine source code but do not include the
TCL testing code and so produce false positive FAILures.
- Add test/scr0?? to highlight code notes
FIXME, TODO, and other source source markers
* Code quality and build tools
- valgrind
Fix all memory related bugs.
- splint
Clean up all items pointed out by splint.
- makedepend
Finish integrating this into the dist/Makefile
* Review code for trailing spaces, tab characters, lines > 79 col
* review dbsql/dbsql.c
General clean-up including changing calls to malloc, free, etc to
__os_malloc, __os_free, etc.
* Review SQLite's latest lemon.c and lempar.c code
Consider updating to the newest versions of the parser generator.
* Use LIST/QUEUE macros for linked lists, queues, etc.
Find/replace all custom code implementing these simple data
structures.
* Review memory allocation code in general
* Consider using MPOOL to manage some of DBSQL state across processes
Function pools and other aspects of the DBSQL runtime need not be
re-created in-memory across multiple processes. When doing this
revisit data structures using the LIST/QUEUE macros and shift them
to the SH_ equivalents.
* Random number generator
SQLite implements its own suggesting that rand32_r() (and other
random number generators) are both truely random and bug free.
Some portion of the VDBE requires random numbers to be,
well... random, or as close as possible.
* Review src/vdbe, finish converting to DBSQL-style
* Investigate the TCL Extension Architecture
http://www.tcl.tk/doc/tea/

490
dist/Makefile.in vendored
View file

@ -1,490 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
srcdir= @srcdir@/../src
tstdir= @srcdir@/../test
distdir= @srcdir@/../dist
builddir=.
##################################################
# Installation directories and permissions.
##################################################
prefix= @prefix@
exec_prefix= @exec_prefix@
bindir= @bindir@
includedir= @includedir@
libdir= @libdir@
docdir= $(prefix)/docs
dmode= 755
emode= 555
fmode= 444
transform=@program_transform_name@
##################################################
# Paths for standard user-level commands.
##################################################
SHELL= @db_cv_path_sh@
ar= @db_cv_path_ar@
awk= @db_cv_path_awk@
chmod= @db_cv_path_chmod@
cp= @db_cv_path_cp@
depend= @db_cv_path_makedepend@
grep= @db_cv_path_grep@
ln= @db_cv_path_ln@
mkdir= @db_cv_path_mkdir@
ranlib= @db_cv_path_ranlib@
rm= @db_cv_path_rm@
rpm= @db_cv_path_rpm@
sed= @db_cv_path_sed@
perl= @db_cv_path_perl@
splint= @db_cv_path_splint@
strip= @db_cv_path_strip@
##################################################
# General library information.
##################################################
DEF_LIB= @DEFAULT_LIB@
DEF_LIB_CXX= @DEFAULT_LIB_CXX@
INSTALLER= @INSTALLER@
LIBTOOL= @LIBTOOL@
POSTLINK= @POSTLINK@
SOLINK= @MAKEFILE_SOLINK@
SOFLAGS= @SOFLAGS@
LIBMAJOR= @DBSQL_VERSION_MAJOR@
LIBVERSION= @DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@
CPPFLAGS= -I$(builddir) -I$(srcdir) @CPPFLAGS@
##################################################
# Lemon parser generator information.
##################################################
LEMON= ./lemon
LEMON_FLAGS=
##################################################
# C API.
##################################################
CFLAGS= -c $(CPPFLAGS) @CFLAGS@
CC= @MAKEFILE_CC@
CCLINK= @MAKEFILE_CCLINK@
LDFLAGS= @LDFLAGS@
LIBS= @LIBS@
LIBSO_LIBS= @LIBSO_LIBS@
libdbsql_base= libdbsql
libdbsql= $(libdbsql_base).a
libdbsql_version= $(libdbsql_base)-$(LIBVERSION).a
libso= $(libdbsql_base)-$(LIBVERSION)@SOSUFFIX@
libso_target= $(libdbsql_base)-$(LIBVERSION).la
libso_default= $(libdbsql_base)@SOSUFFIX@
libso_major= $(libdbsql_base)-$(LIBMAJOR)@SOSUFFIX@
##################################################
# Python Language Bindings
#
# Python support is optional and requires shared libraries.
##################################################
##################################################
# NOTHING BELOW THIS LINE SHOULD EVER NEED TO BE MODIFIED.
##################################################
##################################################
# Source file lists.
##################################################
C_FILES=\
$(srcdir)/api.c $(srcdir)/api_table.c $(srcdir)/cg_attach.c \
$(srcdir)/cg_auth.c $(srcdir)/cg_build.c $(srcdir)/cg_copy.c \
$(srcdir)/cg_date.c $(srcdir)/cg_delete.c $(srcdir)/cg_expr.c \
$(srcdir)/cg_insert.c $(srcdir)/cg_pragma.c $(srcdir)/cg_select.c \
$(srcdir)/cg_trigger.c $(srcdir)/cg_update.c $(srcdir)/cg_where.c \
$(srcdir)/clib/xvprintf.c $(srcdir)/dbsql/dbsql.c \
$(srcdir)/sm.c $(srcdir)/common/hash.c $(srcdir)/lemon/lemon.c \
$(srcdir)/lemon/lempar.c $(srcdir)/os/os.c $(srcdir)/clib/random.c \
$(srcdir)/sql_fns.c $(srcdir)/sql_tokenize.c \
$(srcdir)/cg_vacuum.c $(srcdir)/vdbe.c $(srcdir)/vdbe_method.c \
$(srcdir)/common/dbsql_err.c (srcdir)/clib/snprintf.c \
$(srcdir)/os/os_jtime.c $(srcdir)/os/os_sleep.c $(srcdir)/clib/memcmp.c \
$(srcdir)/clib/strcasecmp.c $(srcdir)/os/dbsql_alloc.c \
$(srcdir)/common/str.c $(srcdir)/common/dbsql_atoi.c \
$(srcdir)/common/dbsql_atof.c $(srcdir)/common/dbsql_fop.c \
$(srcdir)/safety.c $(srcdir)/clib/strdup.c
##################################################
# Object and utility lists.
##################################################
C_OBJS= cg_attach@o@ cg_insert@o@ sql_tokenize@o@ cg_auth@o@ \
cg_copy@o@ api_table@o@ cg_date@o@ api@o@ xvprintf@o@ \
cg_pragma@o@ cg_where@o@ cg_trigger@o@ cg_build@o@ \
sql_fns@o@ random@o@ cg_update@o@ cg_delete@o@ hash@o@ \
cg_expr@o@ opcodes@o@ sql_parser@o@ cg_vacuum@o@ \
vdbe@o@ vdbe_method@o@ sm@o@ snprintf@o@ dbsql_err@o@ \
dbsql_fop@o@ cg_select@o@ os_sleep@o@ os_jtime@o@ memcmp@o@ \
dbsql_atof@o@ safety@o@ dbsql_atoi@o@ strcasecmp@o@ \
strdup@o@ dbsql_alloc@o@ str@o@
LEMON_OBJS=\
lemon@o@
UTIL_PROGS=\
@ADDITIONAL_PROGS@ \
dbsql
##################################################
# List of files installed into the library directory.
##################################################
LIB_INSTALL_FILE_LIST=\
$(libdbsql) \
$(libso) \
$(libso_default) \
$(libso_major) \
$(libdbsql_version) \
$(libso_target) \
$(libtso) \
$(libtso_default) \
$(libtso_major) \
$(libtso_static) \
$(libtso_target)
##################################################
# We're building a standard library or a RPM file hierarchy.
# Note: "all" must be the first target in the Makefile.
##################################################
all: @BUILD_TARGET@
install-strip install: all @INSTALL_TARGET@
##################################################
# Library and standard utilities build.
##################################################
library_build: @INSTALL_LIBS@ @ADDITIONAL_LANG@ $(UTIL_PROGS)
# Static C library named libdbsql.a.
$(libdbsql): $(DEF_LIB)
$(rm) -f $@
test ! -f .libs/$(libdbsql_version) || \
$(ln) -s .libs/$(libdbsql_version) $@
test -f .libs/$(libdbsql_version) || \
(test -f $(libdbsql_version) &&
$(ln) -s $(libdbsql_version) $@)
# Real static C library.
$(libdbsql_version): dbsql_int.h db_int.h sql_parser.h opcodes.h $(C_OBJS)
$(ar) cr $@ $(C_OBJS)
test ! -f $(ranlib) || $(ranlib) $@
# Shared C library.
$(libso_target): dbsql_int.h db_int.h sql_parser.h opcodes.h $(C_OBJS)
$(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(LIBSO_LIBS)
##################################################
# Utilities
##################################################
lemon: $(LEMON_OBJS)
$(CCLINK) -o $@ $(LDFLAGS) \
$(LEMON_OBJS) $(LIBS)
$(POSTLINK) $@
$(cp) $(srcdir)/lemon/lempar.c .
dbsql: $(DEF_LIB) dbsql@o@
$(CCLINK) -o $@ $(LDFLAGS) \
dbsql@o@ $(DEF_LIB) $(LIBS)
$(POSTLINK) $@
##################################################
# Testing.
##################################################
test: $(tstdir)/scr050/dbsql_tclsh
$(tstdir)/scr050/dbsql_tclsh $(tstdir)/quick.test
##################################################
# Library and standard utilities install.
##################################################
library_install: install_setup
library_install: install_include install_lib install_utilities install_docs
uninstall: uninstall_include uninstall_lib uninstall_utilities uninstall_docs
install_setup:
@test -d $(DESTDIR)$(prefix) || \
($(mkdir) -p $(DESTDIR)$(prefix) && \
$(chmod) $(dmode) $(DESTDIR)$(prefix))
INCDOT= dbsql.h @ADDITIONAL_INCS@
install_include:
@echo "Installing DBSQL include files: $(DESTDIR)$(includedir) ..."
@test -d $(DESTDIR)$(includedir) || \
($(mkdir) -p $(DESTDIR)$(includedir) && \
$(chmod) $(dmode) $(DESTDIR)$(includedir))
@cd $(DESTDIR)$(includedir) && $(rm) -f $(INCDOT)
@$(cp) -p $(INCDOT) $(DESTDIR)$(includedir)
@cd $(DESTDIR)$(includedir) && $(chmod) $(fmode) $(INCDOT)
uninstall_include:
@cd $(DESTDIR)$(includedir) && $(rm) -f $(INCDOT)
install_lib:
@echo "Installing DBSQL library: $(DESTDIR)$(libdir) ..."
@test -d $(DESTDIR)$(libdir) || \
($(mkdir) -p $(DESTDIR)$(libdir) && \
$(chmod) $(dmode) $(DESTDIR)$(libdir))
@cd $(DESTDIR)$(libdir) && $(rm) -f $(LIB_INSTALL_FILE_LIST)
@$(INSTALLER) @INSTALL_LIBS@ $(DESTDIR)$(libdir)
@(cd $(DESTDIR)$(libdir) && \
test -f $(libso) && $(ln) -s $(libso) $(libso_default); \
test -f $(libso) && $(ln) -s $(libso) $(libso_major); \
test -f $(libtso) && $(ln) -s $(libtso) $(libtso_default); \
test -f $(libtso) && $(ln) -s $(libtso) $(libtso_major);
uninstall_lib:
@cd $(DESTDIR)$(libdir) && $(rm) -f $(LIB_INSTALL_FILE_LIST)
install_utilities:
@echo "Installing DBSQL utilities: $(DESTDIR)$(bindir) ..."
@test -d $(DESTDIR)$(bindir) || \
($(mkdir) -p $(DESTDIR)$(bindir) && \
$(chmod) $(dmode) $(DESTDIR)$(bindir))
@for i in $(UTIL_PROGS); do \
$(rm) -f $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.exe; \
test -f $$i.exe && i=$$i.exe || true; \
$(INSTALLER) $$i $(DESTDIR)$(bindir)/$$i; \
test -f $(strip) && $(strip) $(DESTDIR)$(bindir)/$$i || true; \
$(chmod) $(emode) $(DESTDIR)$(bindir)/$$i; \
done
uninstall_utilities:
@(cd $(DESTDIR)$(bindir); for i in $(UTIL_PROGS); do \
$(rm) -f $$i $$i.exe; \
done)
##################################################
# RPM, build and install.
##################################################
rpm_build:
@test -f @db_cv_path_rpm_archive@ || \
(echo "@db_cv_path_rpm_archive@: archive file not found" && false)
@$(rm) -rf BUILD RPMS SOURCES SPECS SRPMS RPM_INSTALL
@$(mkdir) -p BUILD && $(chmod) $(dmode) BUILD
@$(mkdir) -p RPMS/i386 && $(chmod) $(dmode) RPMS RPMS/i386
@$(mkdir) -p SOURCES && $(chmod) $(dmode) SOURCES
@$(mkdir) -p SPECS && $(chmod) $(dmode) SPECS
@$(mkdir) -p SRPMS && $(chmod) $(dmode) SRPMS
$(cp) @db_cv_path_rpm_archive@ SOURCES/
$(cp) dbsql.spec SPECS/dbsql.spec
@RPM_BUILD@ --define="`cat rpm-macro-defines`" -ba SPECS/dbsql.spec
rpm_install:
RPM_SRPMS=dbsql-@DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@.@DBSQL_VERSION_PATCH@-1.src.rpm
##################################################
# Remaining standard Makefile targets.
##################################################
CLEAN_LIST=\
lemon
mostly-clean clean:
$(rm) -rf $(C_OBJS)
$(rm) -rf $(UTIL_PROGS) *.exe $(CLEAN_LIST)
$(rm) -rf $(JAVA_CLASSTOP) $(JAVA_EXCLASSTOP)
$(rm) -rf tags *@o@ *~ *.o *.o.lock *.lo core *.core *.loT
$(rm) -rf .libs $(LIB_INSTALL_FILE_LIST)
$(rm) -rf sql_parser.c sql_parser.h sql_parser.out
$(rm) -rf opcodes.c opcodes.h
$(rm) -rf lempar.c
$(rm) -rf test.db test?.db test.db-journal test1.bt data?.txt
$(rm) -f log.*
REALCLEAN_LIST=\
Makefile config.cache config.log config.status \
configure.lineno dbsql.h dbsql.spec dbsql_config.h \
db_int.h dbsql_int.h db_int_def.h rpm-macro-defines win_dbsql.h
distclean maintainer-clean realclean: clean
$(rm) -rf $(REALCLEAN_LIST)
$(rm) -rf libtool
LIBTOOL_DEPS = @LIBTOOL_DEPS@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./deps/config.status $(builddir)/libtool
check dvi info obj TAGS:
@echo "$@: make target not supported" && true
dist:
@echo "$@: make target not supported" && false
##################################################
# TODO Example programs for C.
##################################################
##################################################
# Opcodes are generated from the vdbe.[ch] files.
##################################################
opcodes.c: $(srcdir)/vdbe.c
@echo '/* Automatically generated file. Do not edit */' >opcodes.c
@echo 'char *__opcode_names[] = { "???", ' >>opcodes.c
@$(grep) '^case OP_' $(srcdir)/vdbe.c | \
$(sed) -e 's/^.*OP_/ "/' -e 's/:.*$$/", /' >>opcodes.c
@echo '};' >>opcodes.c
opcodes.h: $(srcdir)/vdbe.c
@echo '/* Automatically generated file. Do not edit */' >opcodes.h
@$(grep) '^case OP_' $(srcdir)/vdbe.c | \
$(sed) -e 's/://' | \
$(awk) '{printf "#define %-30s %3d\n", $$2, ++cnt}' >>opcodes.h
##################################################
# C API build rules.
##################################################
api@o@: $(srcdir)/api.c
$(CC) $(CFLAGS) $?
api_table@o@: $(srcdir)/api_table.c
$(CC) $(CFLAGS) $?
cg_attach@o@: $(srcdir)/cg_attach.c
$(CC) $(CFLAGS) $?
cg_auth@o@: $(srcdir)/cg_auth.c
$(CC) $(CFLAGS) $?
cg_build@o@: $(srcdir)/cg_build.c
$(CC) $(CFLAGS) $?
cg_copy@o@: $(srcdir)/cg_copy.c
$(CC) $(CFLAGS) $?
cg_date@o@: $(srcdir)/cg_date.c
$(CC) $(CFLAGS) $?
cg_delete@o@: $(srcdir)/cg_delete.c
$(CC) $(CFLAGS) $?
cg_expr@o@: $(srcdir)/cg_expr.c
$(CC) $(CFLAGS) $?
cg_insert@o@: $(srcdir)/cg_insert.c
$(CC) $(CFLAGS) $?
cg_pragma@o@: $(srcdir)/cg_pragma.c
$(CC) $(CFLAGS) $?
cg_select@o@: $(srcdir)/cg_select.c
$(CC) $(CFLAGS) $?
cg_trigger@o@: $(srcdir)/cg_trigger.c
$(CC) $(CFLAGS) $?
cg_update@o@: $(srcdir)/cg_update.c
$(CC) $(CFLAGS) $?
cg_where@o@: $(srcdir)/cg_where.c
$(CC) $(CFLAGS) $?
cg_vacuum@o@: $(srcdir)/cg_vacuum.c
$(CC) $(CFLAGS) $?
db_int.h: $(srcdir)/inc/db_int.h
@$(sed) -e 's/__DB_UNIQUE_NAME__/@DB_UNIQUE_NAME@/g' \
$(srcdir)/inc/db_int.h > db_int.h
dbsql_atof@o@: $(srcdir)/common/dbsql_atof.c
$(CC) $(CFLAGS) $?
dbsql_atoi@o@: $(srcdir)/common/dbsql_atoi.c
$(CC) $(CFLAGS) $?
dbsql_err@o@: $(srcdir)/common/dbsql_err.c
$(CC) $(CFLAGS) $?
dbsql_fop@o@: $(srcdir)/common/dbsql_fop.c
$(CC) $(CFLAGS) $?
str@o@: $(srcdir)/common/str.c
$(CC) $(CFLAGS) $?
hash@o@: $(srcdir)/common/hash.c
$(CC) $(CFLAGS) $?
opcodes.c: opcodes.h
opcodes@o@: opcodes.c
$(CC) $(CFLAGS) $?
dbsql_alloc@o@: $(srcdir)/common/dbsql_alloc.c
$(CC) $(CFLAGS) $?
os_jtime@o@: $(srcdir)/os/os_jtime.c
$(CC) $(CFLAGS) $?
os_sleep@o@: $(srcdir)/os/os_sleep.c
$(CC) $(CFLAGS) $?
lemon@o@: $(srcdir)/lemon/lemon.c
$(CC) $(CFLAGS) $?
memcmp@o@: $(srcdir)/clib/memcmp.c
$(CC) $(CFLAGS) $?
xvprintf@o@: $(srcdir)/clib/xvprintf.c
$(CC) $(CFLAGS) $?
random@o@: $(srcdir)/clib/random.c
$(CC) $(CFLAGS) $?
safety@o@: $(srcdir)/safety.c
$(CC) $(CFLAGS) $?
sm@o@: $(srcdir)/sm.c
$(CC) $(CFLAGS) $?
snprintf@o@: $(srcdir)/clib/snprintf.c
$(CC) $(CFLAGS) $?
sql_fns@o@: $(srcdir)/sql_fns.c
$(CC) $(CFLAGS) $?
sql_parser.c: $(srcdir)/sql_parser.y lemon
@$(cp) $(srcdir)/sql_parser.y .
@$(LEMON) $(LEMON_FLAGS) sql_parser.y
@$(cp) ./sql_parser.c ./_sql_parser.c
@$(sed) -e 's/dbsql_parserAlloc/__sql_parser_alloc/g' \
-e 's/dbsql_parserFree/__sql_parser_free/g' \
-e 's/dbsql_parserTrace/__sql_parser_trace/g' \
-e 's/dbsql_parser(/__sql_parser(/g' \
-e 's/__set_stringn/__str_nappend/g' \
-e 's/__set_string/__str_append/g' \
./_sql_parser.c > ./sql_parser.c
@$(rm) -f ./_sql_parser.c
@$(rm) -f ./sql_parser.y
sql_parser.h: sql_parser.c
sql_parser@o@: sql_parser.c
$(CC) $(CFLAGS) $?
sql_tokenize@o@: $(srcdir)/sql_tokenize.c
$(CC) $(CFLAGS) $?
strcasecmp@o@: $(srcdir)/clib/strcasecmp.c
$(CC) $(CFLAGS) $?
strdup@o@: $(srcdir)/clib/strdup.c
$(CC) $(CFLAGS) $?
vdbe@o@: $(srcdir)/vdbe.c
$(CC) $(CFLAGS) $?
vdbe_method@o@: $(srcdir)/vdbe_method.c
$(CC) $(CFLAGS) $?
dbsql.h: $(srcdir)/dbsql.in
@echo dbsql.h is out of date, re-configure to regenerate it.
##################################################
# Utility build rules.
##################################################
dbsql@o@: $(srcdir)/dbsql/dbsql.c
$(CC) $(CFLAGS) $?
##################################################
# Lint.
##################################################
splint:
$(splint) -nof -f $(distdir)/splint.rc -strict \
$(CPPFLAGS) @CFLAGS@ -I. $(C_FILES)
lint: splint
##################################################
# Dependencies
##################################################
#depend:
# @$(depend) -o @o@ $(CPPFLAGS) @CFLAGS@ $(C_FILES)
# @$(perl) -p -i -e 's#^@srcdir@/../src/common/##g' Makefile
# @$(perl) -p -i -e 's#^@srcdir@/../src/os/##g' Makefile
# @$(perl) -p -i -e 's#^@srcdir@/../src/clib/##g' Makefile
# @$(perl) -p -i -e 's#^@srcdir@/../src/lemon/##g' Makefile
# @$(perl) -p -i -e 's#^@srcdir@/../src/##g' Makefile
# DO NOT DELETE THIS LINE -- make depend depends on it.

27
dist/RELEASE vendored
View file

@ -1,27 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
DBSQL_VERSION_MAJOR=0
DBSQL_VERSION_MINOR=4
DBSQL_VERSION_PATCH=0
DBSQL_VERSION="$DBSQL_VERSION_MAJOR.$DBSQL_VERSION_MINOR.$DBSQL_VERSION_PATCH"
DBSQL_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DBSQL_VERSION_MAJOR $DBSQL_VERSION_MINOR`
DBSQL_RELEASE_DATE=`date "+%B %e, %Y"`
DBSQL_VERSION_STRING="DBSQL $DBSQL_VERSION: ($DBSQL_RELEASE_DATE)"

View file

@ -1,26 +0,0 @@
# Features we don't test for, but want the #defines to exist for
# other ports.
AH_TEMPLATE(DBSQL_WIN32,
[We use DBSQL_WIN32 much as one would use _WIN32 -- to specify that
we're using an operating system environment that supports Win32
calls and semantics. We don't use _WIN32 because Cygwin/GCC also
defines _WIN32, even though Cygwin/GCC closely emulates the Unix
environment.])
AH_TEMPLATE(HAVE_FILESYSTEM_NOTZERO,
[Define to 1 if allocated filesystem blocks are not zeroed.])
AH_TEMPLATE(HAVE_UNLINK_WITH_OPEN_FAILURE,
[Define to 1 if unlink of file with open file descriptors will fail.])
AH_BOTTOM([/*
* Exit success/failure macros.
*/
#ifndef HAVE_EXIT_SUCCESS
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#endif
#ifdef DBSQL_WIN32
#include "win_dbsql.h"
#endif])

313
dist/aclocal/cxx.m4 vendored
View file

@ -1,313 +0,0 @@
# C++ language checks
AC_DEFUN(AC_CXX_STDHEADERS, [
AC_SUBST(cxx_have_stdheaders)
AC_MSG_CHECKING(whether C++ supports the ISO C++ standard includes)
AC_LANG_SAVE
AC_LANG([C++])
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[[#include <iostream>]],
[[std::ostream *o; return 0;]])],
db_cv_cxx_have_stdheaders=yes, db_cv_cxx_have_stdheaders=no)
AC_LANG_RESTORE
AC_MSG_RESULT($db_cv_cxx_have_stdheaders)
if test "$db_cv_cxx_have_stdheaders" = yes; then
cxx_have_stdheaders="#define HAVE_CXX_STDHEADERS 1"
fi])
AC_DEFUN(AC_CXX_WSTRING, [
AC_MSG_CHECKING(whether C++ supports the wstring class)
AC_SUBST(WSTRING_decl)
AC_LANG_SAVE
AC_LANG([C++])
AC_LINK_IFELSE(AC_LANG_SOURCE(
[[#include <string>]],
[[using std::wstring;
wstring ws; ws.find_first_of(ws);]]),
[WSTRING_decl="#define HAVE_WSTRING 1" ;
AC_MSG_RESULT(yes)],
[WSTRING_decl="#undef HAVE_WSTRING" ;
AC_MSG_RESULT(no)])
AC_LANG_RESTORE
])
AC_DEFUN(AC_CXX_SUPPORTS_TEMPLATES, [
AC_MSG_CHECKING(whether the C++ compiler supports templates for STL)
AC_LANG_SAVE
AC_LANG([C++])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <iostream>
#include <string>
#include <vector>
]], [[
using std::string;
using std::vector;
namespace dbstl_configure_test {
template<typename T1, typename T2 = int>
class MyClass
{
public:
explicit MyClass(int i) { imem = i;}
MyClass(const T1& t1, const T2& t2, int i)
{
mem1 = t1;
mem2 = t2;
imem = i;
}
template <typename T3>
T2 templ_mem_func(T1 t1, T3 t3)
{
mem2 = t1;
T3 t32 = t3;
T2 t2;
return t2;
}
double templ_mem_func(T1 t1, double t3)
{
mem1 = t1;
double t32 = t3;
return t3;
}
template <typename ReturnType, typename T7, typename T8>
ReturnType templ_mem_func(T7, T8);
operator T1() const {return mem1;}
private:
T1 mem1;
T2 mem2;
int imem;
};
template<typename T1, typename T2>
template <typename ReturnType, typename T7, typename T8>
ReturnType MyClass<T1, T2>::templ_mem_func(T7, T8)
{
ReturnType rt;
return rt;
}
template<>
class MyClass<double, float>
{
public:
explicit MyClass(int i) { imem = i;}
MyClass(const double& t1, const float& t2, int i)
{
mem1 = t1;
mem2 = t2;
imem = i;
}
template <typename T3>
float templ_mem_func(double t1, T3 t3)
{
mem2 = t1;
T3 t32 = t3;
float t2;
return t2;
}
double templ_mem_func(double t1, double t3)
{
mem1 = t1;
double t32 = t3;
return t3;
}
template <typename ReturnType, typename T7, typename T8>
ReturnType templ_mem_func(T7, T8);
operator double() const {return mem1;}
private:
double mem1;
float mem2;
int imem;
};
template <typename ReturnType, typename T7, typename T8>
ReturnType MyClass<double, float>::templ_mem_func(T7, T8)
{
ReturnType rt;
return rt;
}
template <typename T1, typename T2>
class MyClass2 {
public:
MyClass2(const T1& t1, const T2&t2){}
};
// partial specialization: both template parameters have same type
template <typename T>
class MyClass2<T,T> {
public:
MyClass2(const T& t1, const T&t2){}
};
// partial specialization: second type is int
template <typename T>
class MyClass2<T,int> {
public:
MyClass2(const T& t1, const int&t2){}
};
// partial specialization: both template parameters are pointer types
template <typename T1, typename T2>
class MyClass2<T1*,T2*> {
public:
MyClass2(const T1* t1, const T2*t2){}
};
template <typename T>
class MyClass2<T*,T*> {
public:
MyClass2(const T* t1, const T*t2){}
};
template <typename T4, typename T5>
int part_spec_func(T4 t4, T5 t5)
{
// Zero Initialization should work.
T4 t44 = T4();
T5 t55 = T5();
t44 = t4;
t55 = t5;
}
template <typename T4>
int part_spec_func(T4 t4, std::vector<T4> t55)
{
T4 t44 = t4;
std::vector<T4> abc = t55;
}
// maximum of two int values
inline int const& max (int const& a, int const& b)
{
return a<b?b:a;
}
// maximum of two values of any type
template <typename T1, typename T2>
inline T2 const max (T1 const& a, T2 const& b)
{
return a<b?b:a;
}
// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a<b?b:a;
}
// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c);
}
template <typename T>
class Base {
public:
void exit2(){}
Base(){}
};
template <typename T>
class Derived : public Base<T> {
public:
// Call Base<T>() explicitly here, otherwise can't access it.
// Kind of like this->.
Derived() : Base<T>(){}
void foo() {
this->exit2();
}
};
} // dbstl_configure_test
using namespace dbstl_configure_test;], [
char cc = 'a';
int i = 4;
double pi = 3.14;
float gold = 0.618;
MyClass2<int,float> mif(i, gold); // uses MyClass2<T1,T2>
MyClass2<float,float> mff(gold, gold); // uses MyClass2<T,T>
MyClass2<float,int> mfi(gold, i); // uses MyClass2<T,int>
MyClass2<int*,float*> mp(&i, &gold); // uses MyClass2<T1*,T2*>
MyClass2<int*,int*> m(&i, &i); // uses MyClass2<T*, T*>
MyClass<char> obj1(i);
obj1.templ_mem_func(cc, pi);
obj1.templ_mem_func(cc, gold);
obj1.templ_mem_func(i, pi);
obj1.templ_mem_func(cc, cc);
char ch = (char)obj1;
string str1("abc"), str2("def");
MyClass<const char*, std::string> obj2(str1.c_str(), str2, i);
obj2.templ_mem_func("klm", str2);
obj2.templ_mem_func("hij", pi);
// Use j to help distinguish, otherwise unable to use the one defined
// outside of class body.
int j = obj2.templ_mem_func<int, char, char>(cc, cc);
// Call explicitly.
obj2.templ_mem_func<int, float, double>(gold, pi);
const char *pch = (const char*)obj2;
MyClass<double, float> obj3(pi, gold, i);
obj3.templ_mem_func(pi, i);
obj3.templ_mem_func(pi, str1);
obj3.templ_mem_func(pi, pi);
obj3.templ_mem_func(cc, pi);
obj3.templ_mem_func(cc, cc);
double tmpd = (double)obj3;
MyClass<double, float> obj4(i);
obj4.templ_mem_func(pi, i);
obj4.templ_mem_func(pi, str1);
obj4.templ_mem_func(pi, pi);
obj4.templ_mem_func(gold, pi);
tmpd = (double)obj4;
// Function template partial specialization.
part_spec_func(pi, gold);
part_spec_func(gold, i);
part_spec_func(str1, str2);
std::vector<std::string> strv;
part_spec_func(str1, strv);
std::vector<double> dblv;
part_spec_func(pi, dblv);
// Function template overloads and explicit call and deduction.
dbstl_configure_test::max(7, 42, 68); // calls the template for three arguments
dbstl_configure_test::max(7.0, 42.0); // calls max<double> (by argument deduction)
dbstl_configure_test::max('a', 'b'); // calls max<char> (by argument deduction)
dbstl_configure_test::max(7, 42.0);
dbstl_configure_test::max<double>(4,4.2); // instantiate T as double
dbstl_configure_test::max(7, 42); // calls the nontemplate for two ints
dbstl_configure_test::max<>(7, 42); // calls max<int> (by argument deduction)
dbstl_configure_test::max<double, double>(7, 42); // calls max<double> (no argument deduction)
dbstl_configure_test::max('a', 42.7); // calls the nontemplate for two ints
Base<double> bobj;
bobj.exit2();
// Using this-> to access base class members.
Derived<double> dobj;
dobj.foo();
dobj.exit2();
]])], AC_MSG_RESULT(yes), AC_MSG_ERROR(no))
AC_LANG_RESTORE
])

19
dist/aclocal/gcc.m4 vendored
View file

@ -1,19 +0,0 @@
# Version 2.96 of gcc (shipped with RedHat Linux 7.[01] and Mandrake) had
# serious problems.
AC_DEFUN(AC_GCC_CONFIG1, [
AC_CACHE_CHECK([whether we are using gcc version 2.96],
db_cv_gcc_2_96, [
db_cv_gcc_2_96=no
if test "$GCC" = "yes"; then
GCC_VERSION=`${MAKEFILE_CC} --version`
case ${GCC_VERSION} in
2.96*)
db_cv_gcc_2_96=yes;;
esac
fi])
if test "$db_cv_gcc_2_96" = "yes"; then
CFLAGS=`echo "$CFLAGS" | sed 's/-O2/-O/'`
CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2/-O/'`
AC_MSG_WARN([INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE.])
AC_MSG_WARN([GCC OPTIMIZATION LEVEL SET TO -O.])
fi])

8400
dist/aclocal/libtool.m4 vendored

File diff suppressed because it is too large Load diff

View file

@ -1,437 +0,0 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

View file

@ -1,123 +0,0 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

View file

@ -1,24 +0,0 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation,
# Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4245 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.7])
m4_define([LT_PACKAGE_REVISION], [2.4.7])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.7'
macro_revision='2.4.7'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

View file

@ -1,99 +0,0 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

View file

@ -1,255 +0,0 @@
# $Id: options.ac 7 2007-02-03 13:34:17Z gburd $
# Process user-specified options.
AC_DEFUN(AM_OPTIONS_SET, [
AC_MSG_CHECKING(if --enable-utf8-encoding option specified)
AC_ARG_ENABLE(utf8-encoding,
AS_HELP_STRING([--enable-utf8-encoding],
[Encode strings as UTF-8 or ISO-8859.]),, enableval="yes")
db_cv_utf8_strings="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(yes);;
yes) AC_MSG_RESULT(no);;
esac
if test "$cv_utf8_strings" = "yes"; then
ENCODING=UTF8
AC_DEFINE(DBSQL_UTF8_ENCODING)
else
ENCODING=ISO8859
AC_DEFINE(DBSQL_ISO8859_ENCODING)
fi
AH_TEMPLATE(DBSQL_ISO8859_ENCODING,
[Define to use ISO8859 string encoding.])
AH_TEMPLATE(DBSQL_UTF8_ENCODING,
[Define use UTF8 string encoding.])
AC_MSG_CHECKING(if --enable-incore-databases option specified)
AC_ARG_ENABLE(incore-databases,
AS_HELP_STRING([--enable-incore-databases],
[Enable incore databases for ATTACH and OPEN.]),, enableval="yes")
db_cv_incore_databases="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(yes);;
yes) AC_MSG_RESULT(no);;
esac
if test "$db_cv_incore_databases" = "no"; then
INMEMORYDB=0
else
INMEMORYDB=1
fi
AC_DEFINE(INMEMORYDB)
AH_TEMPLATE(INMEMORYDB,
[Define to 1 to enable incore databases for ATTACH and OPEN.])
AC_MSG_CHECKING(if --enable-authentication option specified)
AC_ARG_ENABLE(authentication,
AS_HELP_STRING([--enable-authentication],
[Include authorization validation code.]),, enableval="yes")
db_cv_auth="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(no);;
yes) AC_MSG_RESULT(yes);;
esac
if test "$db_cv_auth" = "no"; then
AC_DEFINE(DBSQL_OMIT_AUTHORIZATION)
fi
AH_TEMPLATE(DBSQL_OMIT_AUTHORIZATION,
[Define to 1 to omit authorization code from the build.])
AC_MSG_CHECKING(if --enable-vacuum option specified)
AC_ARG_ENABLE(vacuum,
AS_HELP_STRING([--enable-vacuum],
[Include the VACUUM command.]),, enableval="yes")
db_cv_auth="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(no);;
yes) AC_MSG_RESULT(yes);;
esac
if test "$db_cv_auth" = "no"; then
AC_DEFINE(DBSQL_OMIT_VACUUM)
fi
AH_TEMPLATE(DBSQL_OMIT_VACUUM,
[Define to 1 to omit the code for the VACCUM command from the build.])
AC_MSG_CHECKING(if --enable-datetime option specified)
AC_ARG_ENABLE(enable-datetime,
AS_HELP_STRING([--enable-datetime],
[Include datetime functions.]),, enableval="yes")
db_cv_datetime="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(no);;
yes) AC_MSG_RESULT(yes);;
esac
if test "$db_cv_datetime" = "no"; then
AC_DEFINE(DBSQL_OMIT_DATETIME_FUNCS)
fi
AH_TEMPLATE(DBSQL_OMIT_DATETIME_FUNCS,
[Define to 1 to omit support for datetime functions from the build.])
AC_MSG_CHECKING([if --with-berkeleydb=DIR option specified])
AC_ARG_WITH(berkeleydb,
[AS_HELP_STRING([--with-berkeleydb=DIR],
[Path of Berkeley DB. [DIR="/usr/local/BerkeleyDB.4.5"]])],
[with_berkeleydb="$withval"], [with_berkeleydb="no"])
AC_MSG_RESULT($with_berkeleydb)
# If --with-berkeleydb isn't specified, assume it's here | wc -l` -gt 0
if test "$with_berkeleydb" = "no"; then
with_berkeleydb="/usr/local/BerkeleyDB.4.5"
fi
DB_PATH="$with_berkeleydb"
if test `ls "$with_berkeleydb"/lib/libdb-*.la 2>/dev/null | wc -l` -gt 0 ; then
AC_MSG_CHECKING([for Berkeley DB version from install tree])
db_version=`ls "$with_berkeleydb"/lib/libdb-*.la | sed 's/.*db-\(.*\).la/\1/'`
AC_MSG_RESULT([$db_version])
echo "$CPPFLAGS" | grep "$with_berkeleydb/include" >/dev/null 2>&1 || CPPFLAGS="$CPPFLAGS -I$with_berkeleydb/include"
if test `ls "$with_berkeleydb"/lib/libdb-$db_version.* 2>/dev/null | wc -l` -gt 0 ; then
LIBSO_LIBS="$LIBS -L$with_berkeleydb/lib -ldb-$db_version"
else
LIBS="$LIBS -l$with_berkeleydb/lib/libdb-$db_version.a"
fi
elif test `ls /usr/local/lib/db?? 2>/dev/null | wc -l` -gt 0 ; then
AC_MSG_CHECKING([if Berkeley DB was installed using BSD ports])
db_num=`ls /usr/local/lib | grep db | grep -v lib | sed -e 's/db//' | sort -n | head -1`
db_version=`echo $db_num | sed 's/\(.\)\(.\)/\1.\2/'`
AC_MSG_RESULT([yes, $db_version])
echo "$CPPFLAGS" | grep /usr/local/include/db$db_num >/dev/null 2>&1 || CPPFLAGS="$CPPFLAGS -I/usr/local/include/db$db_num"
if test `ls /usr/local/lib/libdb-$db_version.* 2>/dev/null | wc -l` -gt 0 ; then
LIBSO_LIBS="$LIBS -L/usr/local/lib -ldb-$db_version"
else
LIBS="$LIBS -l/usr/local/lib/libdb-$db_version.a"
fi
else
AC_MSG_ERROR([$with_berkeleydb not a valid Berkeley DB install tree.])
fi
AC_MSG_CHECKING([if --with-db-uniquename=NAME option specified])
AC_ARG_WITH(db-uniquename,
[AS_HELP_STRING([--with-db-uniquename=NAME],
[Unique name used when building DB library.])],
[with_db_uniquename="$withval"], [with_db_uniquename="no"])
if test "$with_db_uniquename" = "no"; then
db_cv_uniquename="no"
DB_UNIQUE_NAME=""
AC_MSG_RESULT($with_db_uniquename)
else
db_cv_uniquename="yes"
if test "$with_db_uniquename" = "yes"; then
DB_UNIQUE_NAME="__EDIT_DB_VERSION_UNIQUE_NAME__"
else
DB_UNIQUE_NAME="$with_db_uniquename"
fi
AC_MSG_RESULT($DB_UNIQUE_NAME)
fi
AC_MSG_CHECKING(if --enable-incore-temp-databases option specified)
AC_ARG_ENABLE(incore-temp-databases,
AS_HELP_STRING([--enable-incore-temp-databases],
[Enable incore databases for temporary tables.]),, enableval="no")
db_cv_incore_temp_databases="$enableval"
case "$db_cv_incore_temp_databases" in
never)
TEMP_STORE=0
AC_MSG_RESULT([never])
;;
no)
INMEMORYDB=1
TEMP_STORE=1
AC_MSG_RESULT([no])
;;
always)
INMEMORYDB=1
TEMP_STORE=3
AC_MSG_RESULT([always])
;;
*)
INMEMORYDB=1
TEMP_STORE=2
AC_MSG_RESULT([yes])
;;
esac
AC_DEFINE(INMEMORYDB)
AH_TEMPLATE(INMEMORYDB,
[Define to 1 to enable memory resident databases.])
AC_DEFINE(TEMP_STORE)
AH_TEMPLATE(TEMP_STORE,
[Determines where TEMP databases can be stored, see table in source code.])
AC_MSG_CHECKING(if --disable-statistics option specified)
AC_ARG_ENABLE(statistics,
AS_HELP_STRING([--disable-statistics],
[Do not build statistics support.]),, enableval="yes")
db_cv_build_statistics="$enableval"
case "$enableval" in
no) AC_MSG_RESULT(yes);;
yes) AC_MSG_RESULT(no);;
esac
AC_MSG_CHECKING(if --enable-sqlite-compat option specified)
AC_ARG_ENABLE(sqlite-compat,
[AS_HELP_STRING([--enable-sqlite-compat],
[Build SQLite compatibility API.])],
[db_cv_sqlite_compat="$enable_sqlite_compat"],
[db_cv_sqlite_compat="no"])
AC_MSG_RESULT($db_cv_sqlite_compat)
AC_MSG_CHECKING(if --enable-soundex-sqlfn option specified)
AC_ARG_ENABLE(soundex-sqlfn,
[AS_HELP_STRING([--enable-soundex-sqlfn],
[Include soundex() sql function support.])],
[db_cv_sqlite_compat="$enable_soundex_sqlfn"],
[db_cv_sqlite_compat="no"])
AC_MSG_RESULT($db_cv_soundex_sqlfn)
AC_MSG_CHECKING(if --enable-posixmutexes option specified)
AC_ARG_ENABLE(posixmutexes,
[AS_HELP_STRING([--enable-posixmutexes],
[Force use of POSIX standard mutexes.])],
[db_cv_posixmutexes="$enable_posixmutexes"], [db_cv_posixmutexes="no"])
AC_MSG_RESULT($db_cv_posixmutexes)
AC_MSG_CHECKING(if --enable-debug option specified)
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug],
[Build a debugging version.])],
[db_cv_debug="$enable_debug"], [db_cv_debug="no"])
AC_MSG_RESULT($db_cv_debug)
AC_MSG_CHECKING(if --enable-diagnostic option specified)
AC_ARG_ENABLE(diagnostic,
[AS_HELP_STRING([--enable-diagnostic],
[Build a version with run-time diagnostics.])],
[db_cv_diagnostic="$enable_diagnostic"], [db_cv_diagnostic="no"])
AC_MSG_RESULT($db_cv_diagnostic)
AC_MSG_CHECKING(if --enable-tcl option specified)
AC_ARG_ENABLE(tcl,
[AS_HELP_STRING([--enable-tcl],
[Build Tcl API.])],
[db_cv_tcl="$enable_tcl"], [db_cv_tcl="no"])
AC_MSG_RESULT($db_cv_tcl)
AC_MSG_CHECKING([if --with-tcl=DIR option specified])
AC_ARG_WITH(tcl,
[AS_HELP_STRING([--with-tcl=DIR],
[Directory location of tclConfig.sh.])],
[with_tclconfig="$withval"], [with_tclconfig="no"])
AC_MSG_RESULT($with_tclconfig)
AC_MSG_CHECKING(if --enable-test option specified)
AC_ARG_ENABLE(test,
[AS_HELP_STRING([--enable-test],
[Configure to run the test suite.])],
[db_cv_test="$enable_test"], [db_cv_test="no"])
AC_MSG_RESULT($db_cv_test)
# Test requires Tcl
if test "$db_cv_test" = "yes"; then
if test "$db_cv_tcl" = "no"; then
AC_MSG_ERROR([--enable-test requires --enable-tcl])
fi
fi])

View file

@ -1,118 +0,0 @@
# $Id: programs.ac 7 2007-02-03 13:34:17Z gburd $
# Check for programs used in building/installation.
AC_DEFUN(AM_PROGRAMS_SET, [
AC_CHECK_TOOL(db_cv_path_ar, ar, missing_ar)
if test "$db_cv_path_ar" = missing_ar; then
AC_MSG_ERROR([No ar utility found.])
fi
AC_CHECK_TOOL(db_cv_path_chmod, chmod, missing_chmod)
if test "$db_cv_path_chmod" = missing_chmod; then
AC_MSG_ERROR([No chmod utility found.])
fi
AC_CHECK_TOOL(db_cv_path_sed, sed, missing_sed)
if test "$db_cv_path_sed" = missing_sed; then
AC_MSG_ERROR([No sed utility found.])
fi
AC_CHECK_TOOL(db_cv_path_perl, perl, missing_perl)
if test "$db_cv_path_perl" = missing_perl; then
AC_MSG_ERROR([No perl utility found.])
fi
AC_CHECK_TOOL(db_cv_path_makedepend, makedepend, missing_makedepend)
if test "$db_cv_path_makedepend" = missing_makedepend; then
AC_MSG_RESULT([no])
db_cv_path_makedepend=echo
fi
AC_CHECK_TOOL(db_cv_path_splint, splint, missing_splint)
if test "$db_cv_path_splint" = missing_splint; then
AC_MSG_RESULT([no])
db_cv_path_splint=echo
fi
AC_CHECK_TOOL(db_cv_path_python, python, missing_python)
if test "$db_cv_path_python" = missing_python; then
AC_MSG_RESULT([no])
db_cv_path_python=echo
fi
AC_CHECK_TOOL(db_cv_path_grep, grep, missing_grep)
if test "$db_cv_path_grep" = missing_grep; then
AC_MSG_ERROR([No grep utility found.])
fi
AC_CHECK_TOOL(db_cv_path_awk, awk, missing_awk)
if test "$db_cv_path_awk" = missing_awk; then
AC_MSG_ERROR([No awk utility found.])
fi
AC_CHECK_TOOL(db_cv_path_cp, cp, missing_cp)
if test "$db_cv_path_cp" = missing_cp; then
AC_MSG_ERROR([No cp utility found.])
fi
if test "$db_cv_rpm" = "yes"; then
AC_CHECK_TOOL(path_ldconfig, ldconfig, missing_ldconfig)
AC_PATH_PROG(db_cv_path_ldconfig, $path_ldconfig, missing_ldconfig)
if test "$db_cv_path_ldconfig" != missing_ldconfig; then
RPM_POST_INSTALL="%post -p $db_cv_path_ldconfig"
RPM_POST_UNINSTALL="%postun -p $db_cv_path_ldconfig"
fi
fi
AC_CHECK_TOOL(db_cv_path_ln, ln, missing_ln)
if test "$db_cv_path_ln" = missing_ln; then
AC_MSG_ERROR([No ln utility found.])
fi
AC_CHECK_TOOL(db_cv_path_mkdir, mkdir, missing_mkdir)
if test "$db_cv_path_mkdir" = missing_mkdir; then
AC_MSG_ERROR([No mkdir utility found.])
fi
# We need a complete path for ranlib, because it doesn't exist on some
# architectures because the ar utility packages the library itself.
AC_CHECK_TOOL(path_ranlib, ranlib, missing_ranlib)
AC_PATH_PROG(db_cv_path_ranlib, $path_ranlib, missing_ranlib)
AC_CHECK_TOOL(db_cv_path_rm, rm, missing_rm)
if test "$db_cv_path_rm" = missing_rm; then
AC_MSG_ERROR([No rm utility found.])
fi
if test "$db_cv_rpm" = "yes"; then
AC_CHECK_TOOL(db_cv_path_rpm, rpm, missing_rpm)
if test "$db_cv_path_rpm" = missing_rpm; then
AC_MSG_ERROR([No rpm utility found.])
fi
fi
# We need a complete path for sh, because some implementations of make
# get upset if SHELL is set to just the command name.
AC_CHECK_TOOL(path_sh, sh, missing_sh)
AC_PATH_PROG(db_cv_path_sh, $path_sh, missing_sh)
if test "$db_cv_path_sh" = missing_sh; then
AC_MSG_ERROR([No sh utility found.])
fi
# Don't strip the binaries if --enable-debug was specified.
if test "$db_cv_debug" = yes; then
db_cv_path_strip=debug_build_no_strip
else
AC_CHECK_TOOL(path_strip, strip, missing_strip)
AC_PATH_PROG(db_cv_path_strip, $path_strip, missing_strip)
fi
if test "$db_cv_test" = "yes"; then
AC_CHECK_TOOL(db_cv_path_kill, kill, missing_kill)
if test "$db_cv_path_kill" = missing_kill; then
AC_MSG_ERROR([No kill utility found.])
fi
fi
])

View file

@ -1,47 +0,0 @@
# $Id: readline.ac 7 2007-02-03 13:34:17Z gburd $
# Find a readline compatible library.
AC_DEFUN([VL_LIB_READLINE], [
AC_CACHE_CHECK([for a readline compatible library],
vl_cv_lib_readline, [
ORIG_LIBS="$LIBS"
for readline_lib in readline edit editline; do
for termcap_lib in "" termcap curses ncurses; do
if test -z "$termcap_lib"; then
TRY_LIB="-l$readline_lib"
else
TRY_LIB="-l$readline_lib -l$termcap_lib"
fi
LIBS="$ORIG_LIBS $TRY_LIB"
AC_TRY_LINK_FUNC(readline, vl_cv_lib_readline="$TRY_LIB")
if test -n "$vl_cv_lib_readline"; then
break
fi
done
if test -n "$vl_cv_lib_readline"; then
break
fi
done
if test -z "$vl_cv_lib_readline"; then
vl_cv_lib_readline="no"
LIBS="$ORIG_LIBS"
fi
])
if test "$vl_cv_lib_readline" != "no"; then
AC_DEFINE(HAVE_LIBREADLINE, 1,
[Define if you have a readline compatible library])
AC_CHECK_HEADERS(readline.h readline/readline.h)
AC_CACHE_CHECK([whether readline supports history],
vl_cv_lib_readline_history, [
vl_cv_lib_readline_history="no"
AC_TRY_LINK_FUNC(add_history, vl_cv_lib_readline_history="yes")
])
if test "$vl_cv_lib_readline_history" = "yes"; then
AC_DEFINE(HAVE_READLINE_HISTORY, 1,
[Define if your readline library has \`add_history'])
AC_CHECK_HEADERS(history.h readline/history.h)
fi
fi
])dnl

View file

@ -1,75 +0,0 @@
# $Id$
# Determine shared object suffixes.
#
# Our method is to use the libtool variable $library_names_spec,
# set by using LT_INIT. This variable is a snippet of shell
# defined in terms of $versuffix, $release, $libname and $module
# We want to eval it and grab the suffix used for shared objects.
# By setting $module to yes/no, we obtain the suffixes
# used to create dlloadable, or java loadable modules.
# On many (*nix) systems, these all evaluate to .so, but there
# are some notable exceptions.
# Before calling this macro, libtool must have been configured.
# This macro is used internally to discover the suffix for the current
# settings of $module. The result is stored in $_SOSUFFIX.
AC_DEFUN(_SOSUFFIX_INTERNAL, [
versuffix=""
release=""
libname=libfoo
eval _SOSUFFIX=\"$shrext_cmds\"
if test "$_SOSUFFIX" = "" ; then
_SOSUFFIX=".so"
if test "$enable_shared" != "yes"; then
if test "$_SOSUFFIX_MESSAGE" = ""; then
_SOSUFFIX_MESSAGE=yes
AC_MSG_WARN([libtool may not know about this architecture.])
AC_MSG_WARN([assuming $_SOSUFFIX suffix for dynamic libraries.])
fi
fi
fi
])
# SOSUFFIX_CONFIG will set the variable SOSUFFIX to be the
# shared library extension used for general linking, not dlopen.
AC_DEFUN(SOSUFFIX_CONFIG, [
AC_MSG_CHECKING([SOSUFFIX from libtool])
module=no
_SOSUFFIX_INTERNAL
SOSUFFIX=$_SOSUFFIX
AC_MSG_RESULT($SOSUFFIX)
AC_SUBST(SOSUFFIX)
])
# MODSUFFIX_CONFIG will set the variable MODSUFFIX to be the
# shared library extension used for dlopen'ed modules.
# To discover this, we set $module, simulating libtool's -module option.
AC_DEFUN(MODSUFFIX_CONFIG, [
AC_MSG_CHECKING([MODSUFFIX from libtool])
module=yes
_SOSUFFIX_INTERNAL
MODSUFFIX=$_SOSUFFIX
AC_MSG_RESULT($MODSUFFIX)
AC_SUBST(MODSUFFIX)
])
# JMODSUFFIX_CONFIG will set the variable JMODSUFFIX to be the
# shared library extension used JNI modules opened by Java.
# To discover this, we set $jnimodule, simulating libtool's -shrext option.
##########################################################################
# Robert Boehne: Not much point in this macro any more because apparently
# Darwin is the only OS that wants or needs the .jnilib extension.
##########################################################################
AC_DEFUN(JMODSUFFIX_CONFIG, [
AC_MSG_CHECKING([JMODSUFFIX from libtool])
module=yes
_SOSUFFIX_INTERNAL
if test `uname` = "Darwin"; then
JMODSUFFIX=".jnilib"
else
JMODSUFFIX=$_SOSUFFIX
fi
AC_MSG_RESULT($JMODSUFFIX)
AC_SUBST(JMODSUFFIX)
])

128
dist/aclocal/tcl.m4 vendored
View file

@ -1,128 +0,0 @@
# $Id: tcl.ac 7 2007-02-03 13:34:17Z gburd $
# The SC_* macros in this file are from the unix/tcl.m4 files in the Tcl
# 8.3.0 distribution, with some minor changes. For this reason, license
# terms for the Berkeley DB distribution dist/aclocal/tcl.m4 file are as
# follows (copied from the license.terms file in the Tcl 8.3 distribution):
#
# This software is copyrighted by the Regents of the University of
# California, Sun Microsystems, Inc., Scriptics Corporation,
# and other parties. The following terms apply to all files associated
# with the software unless explicitly disclaimed in individual files.
#
# The authors hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose, provided
# that existing copyright notices are retained in all copies and that this
# notice is included verbatim in any distributions. No written agreement,
# license, or royalty fee is required for any of the authorized uses.
# Modifications to this software may be copyrighted by their authors
# and need not follow the licensing terms described here, provided that
# the new terms are clearly indicated on the first page of each file where
# they apply.
#
# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
# MODIFICATIONS.
#
# GOVERNMENT USE: If you are acquiring this software on behalf of the
# U.S. government, the Government shall have only "Restricted Rights"
# in the software and related documentation as defined in the Federal
# Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
# are acquiring the software on behalf of the Department of Defense, the
# software shall be classified as "Commercial Computer Software" and the
# Government shall have only "Restricted Rights" as defined in Clause
# 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
# authors grant the U.S. Government and others acting in its behalf
# permission to use and distribute the software in accordance with the
# terms specified in this license.
AC_DEFUN(SC_PATH_TCLCONFIG, [
AC_CACHE_VAL(ac_cv_c_tclconfig,[
# First check to see if --with-tclconfig was specified.
if test x"${with_tclconfig}" != x; then
if test -f "${with_tclconfig}/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
else
AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
fi
fi
# check in a few common install locations
if test x"${ac_cv_c_tclconfig}" = x ; then
for i in `ls -d /usr/local/lib 2>/dev/null` ; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig=`(cd $i; pwd)`
break
fi
done
fi
])
if test x"${ac_cv_c_tclconfig}" = x ; then
TCL_BIN_DIR="# no Tcl configs found"
AC_MSG_ERROR(can't find Tcl configuration definitions)
else
TCL_BIN_DIR=${ac_cv_c_tclconfig}
fi
AC_SUBST(TCL_BIN_DIR)
])
AC_DEFUN(SC_LOAD_TCLCONFIG, [
AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh])
if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
AC_MSG_RESULT([loading])
. $TCL_BIN_DIR/tclConfig.sh
else
AC_MSG_RESULT([file not found])
fi
# DBSQL requires at least version 8.4.
if test ${TCL_MAJOR_VERSION} -lt 8 \
-o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then
AC_MSG_ERROR([Berkeley DB requires Tcl version 8.4 or better.])
fi
if test x"$TCL_INCLUDE_SPEC" != x; then
TCL_CFLAGS="$TCL_INCLUDE_SPEC"
fi
AC_SUBST(TCL_LD_FLAGS)
AC_SUBST(TCL_LIBS)
AC_SUBST(TCL_LIB_SPEC)
])
# Optional Tcl API.
AC_DEFUN(AM_TCL_LOAD, [
if test "$db_cv_tcl" = "yes"; then
if test `$LIBTOOL_PROG --config | grep build_libtool_libs | grep no` 2>/dev/null; then
AC_MSG_ERROR([Tcl requires shared libraries])
fi
SC_PATH_TCLCONFIG
SC_LOAD_TCLCONFIG
if test x"$TCL_INCLUDE_SPEC" != x && test -f "$TCL_INCLUDE_SPEC/tcl.h"; then
TCL_CFLAGS="${TCL_CFLAGS} -I$TCL_INCLUDE_SPEC"
fi
INSTALL_LIBS="${INSTALL_LIBS} \$(libtso_target)"
TCL_TCLSH="${TCL_PREFIX}/bin/tclsh${TCL_VERSION}"
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_LIB_FILE)
AC_SUBST(TCL_CFLAGS)
AC_SUBST(TCL_TCLSH)
fi])

218
dist/aclocal/types.m4 vendored
View file

@ -1,218 +0,0 @@
# $Id$
# Check the sizes we know about, and see if any of them match what's needed.
#
# Prefer ints to anything else, because read, write and others historically
# returned an int.
AC_DEFUN(AM_SEARCH_USIZES, [
case "$3" in
"$ac_cv_sizeof_unsigned_int")
$1="typedef unsigned int $2;";;
"$ac_cv_sizeof_unsigned_char")
$1="typedef unsigned char $2;";;
"$ac_cv_sizeof_unsigned_short")
$1="typedef unsigned short $2;";;
"$ac_cv_sizeof_unsigned_long")
$1="typedef unsigned long $2;";;
"$ac_cv_sizeof_unsigned_long_long")
$1="typedef unsigned long long $2;";;
*)
if test "$4" != "notfatal"; then
AC_MSG_ERROR([No unsigned $3-byte integral type])
fi;;
esac])
AC_DEFUN(AM_SEARCH_SSIZES, [
case "$3" in
"$ac_cv_sizeof_int")
$1="typedef int $2;";;
"$ac_cv_sizeof_char")
$1="typedef char $2;";;
"$ac_cv_sizeof_short")
$1="typedef short $2;";;
"$ac_cv_sizeof_long")
$1="typedef long $2;";;
"$ac_cv_sizeof_long_long")
$1="typedef long long $2;";;
*)
if test "$4" != "notfatal"; then
AC_MSG_ERROR([No signed $3-byte integral type])
fi;;
esac])
# Check for the standard system types.
AC_DEFUN(AM_TYPES, [
# db.h includes <sys/types.h> and <stdio.h>, not the other default includes
# autoconf usually includes. For that reason, we specify a set of includes
# for all type checking tests. [#5060]
#
# C99 says types should be in <stdint.h>; include <stdint.h> if it exists.
#
# Some systems have types in <stddef.h>; include <stddef.h> if it exists.
#
# IBM's OS/390 and z/OS releases have types in <inttypes.h> not also found
# in <sys/types.h>; include <inttypes.h> if it exists.
db_includes="#include <sys/types.h>"
AC_SUBST(inttypes_h_decl)
AC_CHECK_HEADER(inttypes.h, [
db_includes="$db_includes
#include <inttypes.h>"
inttypes_h_decl="#include <inttypes.h>"])
# IRIX has stdint.h that is only available when using c99 (i.e. __c99
# is defined). Problem with having it in a public header is that a c++
# compiler cannot #include <db.h> if db.h #includes stdint.h, so we
# need to check that stdint.h is available for all cases. Also the
# IRIX compiler does not exit with a non-zero exit code when it sees
# #error, so we actually need to use the header for the compiler to fail.
AC_SUBST(stdint_h_decl)
AC_MSG_CHECKING(for stdint.h)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <stdint.h>
int main() {
uint_least8_t x=0;
return x;
}]])],[AC_MSG_RESULT(yes)
if test "$db_cv_cxx" = "yes"; then
AC_MSG_CHECKING([if stdint.h can be used by C++])
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <stdint.h>
int main() {
uint_least8_t x=0;
return x;
}]])],[AC_MSG_RESULT(yes)
stdint_h_decl="#include <stdint.h>"
db_includes="$db_includes
#include <stdint.h>"
],[AC_MSG_RESULT(no)
stdint_h_decl="#ifndef __cplusplus
#include <stdint.h>
#endif"
db_includes="$db_includes
#ifndef __cplusplus
#include <stdint.h>
#endif"
])
AC_LANG_POP
else
stdint_h_decl="#include <stdint.h>"
db_includes="$db_includes
#include <stdint.h>"
fi],[AC_MSG_RESULT(no)])
AC_SUBST(stddef_h_decl)
AC_CHECK_HEADER(stddef.h, [
db_includes="$db_includes
#include <stddef.h>"
stddef_h_decl="#include <stddef.h>"])
AC_SUBST(unistd_h_decl)
AC_CHECK_HEADER(unistd.h, [
db_includes="$db_includes
#include <unistd.h>"
unistd_h_decl="#include <unistd.h>"])
db_includes="$db_includes
#include <stdio.h>"
# We need to know the sizes of various objects on this system.
AC_CHECK_SIZEOF(char,, $db_includes)
AC_CHECK_SIZEOF(unsigned char,, $db_includes)
AC_CHECK_SIZEOF(short,, $db_includes)
AC_CHECK_SIZEOF(unsigned short,, $db_includes)
AC_CHECK_SIZEOF(int,, $db_includes)
AC_CHECK_SIZEOF(unsigned int,, $db_includes)
AC_CHECK_SIZEOF(long,, $db_includes)
AC_CHECK_SIZEOF(unsigned long,, $db_includes)
AC_CHECK_SIZEOF(long long,, $db_includes)
AC_CHECK_SIZEOF(unsigned long long,, $db_includes)
AC_CHECK_SIZEOF(char *,, $db_includes)
AC_CHECK_SIZEOF(long double,, $db_includes)
# We look for u_char, u_short, u_int, u_long -- if we can't find them,
# we create our own.
AC_SUBST(u_char_decl)
AC_CHECK_TYPE(u_char,,
[u_char_decl="typedef unsigned char u_char;"], $db_includes)
AC_SUBST(u_short_decl)
AC_CHECK_TYPE(u_short,,
[u_short_decl="typedef unsigned short u_short;"], $db_includes)
AC_SUBST(u_int_decl)
AC_CHECK_TYPE(u_int,,
[u_int_decl="typedef unsigned int u_int;"], $db_includes)
AC_SUBST(u_long_decl)
AC_CHECK_TYPE(u_long,,
[u_long_decl="typedef unsigned long u_long;"], $db_includes)
# We look for fixed-size variants of u_char, u_short, u_int, u_long as well.
AC_SUBST(u_int8_decl)
AC_CHECK_TYPE(u_int8_t,,
[AM_SEARCH_USIZES(u_int8_decl, u_int8_t, 1)], $db_includes)
AC_SUBST(u_int16_decl)
AC_CHECK_TYPE(u_int16_t,,
[AM_SEARCH_USIZES(u_int16_decl, u_int16_t, 2)], $db_includes)
AC_SUBST(int16_decl)
AC_CHECK_TYPE(int16_t,,
[AM_SEARCH_SSIZES(int16_decl, int16_t, 2)], $db_includes)
AC_SUBST(u_int32_decl)
AC_CHECK_TYPE(u_int32_t,,
[AM_SEARCH_USIZES(u_int32_decl, u_int32_t, 4)], $db_includes)
AC_SUBST(int32_decl)
AC_CHECK_TYPE(int32_t,,
[AM_SEARCH_SSIZES(int32_decl, int32_t, 4)], $db_includes)
AC_SUBST(u_int64_decl)
AC_CHECK_TYPE(u_int64_t,,
[AM_SEARCH_USIZES(u_int64_decl, u_int64_t, 8, notfatal)], $db_includes)
AC_SUBST(int64_decl)
AC_CHECK_TYPE(int64_t,,
[AM_SEARCH_SSIZES(int64_decl, int64_t, 8, notfatal)], $db_includes)
AC_SUBST(long_double_decl)
AC_CHECK_TYPE(long double,
[long_double_decl="typedef long double long_double_t;"],
[long_double_decl="typedef long double long_double_t;"], $db_includes)
# No currently autoconf'd systems lack FILE, off_t pid_t, size_t, time_t.
#
# We require them, we don't try to substitute our own if we can't find them.
AC_SUBST(FILE_t_decl)
AC_CHECK_TYPE(FILE *,, AC_MSG_ERROR([No FILE type.]), $db_includes)
AC_SUBST(off_t_decl)
AC_CHECK_TYPE(off_t,, AC_MSG_ERROR([No off_t type.]), $db_includes)
AC_SUBST(pid_t_decl)
AC_CHECK_TYPE(pid_t,, AC_MSG_ERROR([No pid_t type.]), $db_includes)
AC_SUBST(size_t_decl)
AC_CHECK_TYPE(size_t,, AC_MSG_ERROR([No size_t type.]), $db_includes)
AC_SUBST(time_t_decl)
AC_CHECK_TYPE(time_t,, AC_MSG_ERROR([No time_t type.]), $db_includes)
# Check for ssize_t -- if none exists, find a signed integral type that's
# the same size as a size_t.
AC_CHECK_SIZEOF(size_t,, $db_includes)
AC_SUBST(ssize_t_decl)
AC_CHECK_TYPE(ssize_t,,
[AM_SEARCH_SSIZES(ssize_t_decl, ssize_t, $ac_cv_sizeof_size_t)],
$db_includes)
# Check for uintmax_t -- if none exists, find the largest unsigned integral
# type available.
AC_SUBST(uintmax_t_decl)
AC_CHECK_TYPE(uintmax_t,, [AC_CHECK_TYPE(unsigned long long,
[uintmax_t_decl="typedef unsigned long long uintmax_t;"],
[uintmax_t_decl="typedef unsigned long uintmax_t;"], $db_includes)])
# Check for uintptr_t -- if none exists, find an integral type which is
# the same size as a pointer.
AC_SUBST(uintptr_t_decl)
AC_CHECK_TYPE(uintptr_t,,
[AM_SEARCH_USIZES(uintptr_t_decl, uintptr_t, $ac_cv_sizeof_char_p)])
])

135
dist/buildrel vendored
View file

@ -1,135 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build the distribution package.
# A set of commands intended to be cut and pasted into a csh window.
#
# Development tree, release home.
setenv D `pwd`
# Update the release number.
cd $D/dist
cvs -q update RELEASE
vi RELEASE
setenv VERSION `sh -c '. RELEASE; echo $DBSQL_VERSION'`
echo "Version: $VERSION"
# Make sure the source tree is up-to-date
cd $D && cvs -q update
# Build the documentation.
cd db.docs && cvs -q update
cd db.docs && sh build ../db.rel clean && sh build ../db.rel |& sed '/.html$/d'
cd db.docs && sh build ../db.rel javadoc
# Generate new support files, commit anything that's changed.
cd $D/dist && sh s_all
cd $D && cvs -q commit
# Copy a development tree into a release tree.
setenv R /var/tmp/db-$VERSION
rm -rf $R && mkdir -p $R
cd $D && cvs -q status | \
grep "Repository revision" | \
sed -e 's;.*CVSROOT/db/;;' \
-e 's;.*CVSROOT/;;' \
-e 's;,v$;;' | pax -rw $R/
# Copy the already-built documentation into place
rm -rf $R/docs && cp -r $D/docs $R/docs
# Remove source directories we don't distribute.
cd $R && rm -rf docs_src docs/api_java
cd $R && rm -rf test/TODO test/upgrade test_perf test_purify
cd $R && rm -rf test_server test_thread test_vxworks test_xa
cd $R && rm -rf java/src/com/sleepycat/xa
# Fix symbolic links and permissions.
cd $R/dist && sh s_perm
cd $R/dist && sh s_symlink
# Build a version.
cd $R && rm -rf build_run && mkdir build_run
cd $R/build_run && ~bostic/bin/dbconf && make >& mklog
# Smoke test.
cd $R/build_run && ./ex_access
# Check the install
cd $R/build_run && make prefix=`pwd`/BDB install
# Build a small-footprint version.
cd $R && rm -rf build_run && mkdir build_run
cd $R/build_run && ../dist/configure --enable-smallbuild && make >& mklog
# Remove the build directory
cd $R && rm -rf build_run
# ACQUIRE ROOT PRIVILEGES
cd $R && find . -type d | xargs chmod 775
cd $R && find . -type f | xargs chmod 444
cd $R && chmod 664 build_win32/*.dsp
cd $R/dist && sh s_perm
chown -R 100 $R
chgrp -R 100 $R
# DISCARD ROOT PRIVILEGES
# Create the crypto tar archive release.
setenv T "$R/../db-$VERSION.tar.gz"
cd $R/.. && tar cf - db-$VERSION | gzip --best > $T
chmod 444 $T
# Create the non-crypto tree.
setenv RNC "$R/../db-$VERSION.NC"
rm -rf $RNC $R/../__TMP && mkdir $R/../__TMP
cd $R/../__TMP && gzcat $T | tar xpf - && mv -i db-$VERSION $RNC
cd $R && rm -rf $R/../__TMP
cd $RNC/dist && sh s_crypto
# ACQUIRE ROOT PRIVILEGES
cd $RNC && find . -type d | xargs chmod 775
cd $RNC && find . -type f | xargs chmod 444
cd $RNC && chmod 664 build_win32/*.dsp
cd $RNC/dist && sh s_perm
chown -R 100 $RNC
chgrp -R 100 $RNC
# DISCARD ROOT PRIVILEGES
# Create the non-crypto tar archive release.
setenv T "$R/../db-$VERSION.NC.tar.gz"
cd $RNC/.. && tar cf - db-$VERSION.NC | gzip --best > $T
chmod 444 $T
# Remove tags files. They're large and we don't want to store symbolic links
# in the zip archive for portability reasons.
# ACQUIRE ROOT PRIVILEGES
cd $R && rm -f `find . -name 'tags'`
cd $RNC && rm -f `find . -name 'tags'`
# DISCARD ROOT PRIVILEGES
# Create the crypto zip archive release.
setenv T "$R/../db-$VERSION.zip"
cd $R/.. && zip -r - db-$VERSION > $T
chmod 444 $T
# Create the non-crypto zip archive release.
setenv T "$R/../db-$VERSION.NC.zip"
cd $RNC/.. && zip -r - db-$VERSION.NC > $T
chmod 444 $T

1803
dist/config.guess vendored

File diff suppressed because it is too large Load diff

1895
dist/config.sub vendored

File diff suppressed because it is too large Load diff

527
dist/configure.ac vendored
View file

@ -1,527 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2009 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
# Process this file with autoconf to produce a configure script.
PACKAGE=dbsql
AC_INIT([DBSQL],[__EDIT_DBSQL_VERSION__],[support@dbsql.org],[dbsql-__EDIT_DBSQL_VERSION__])
AC_LANG(C)
AC_CONFIG_SRCDIR([../src/clib/memcmp.c])
AC_CONFIG_HEADERS([dbsql_config.h:config.hin])
# Configure setup.
AC_CANONICAL_HOST()
AC_ARG_PROGRAM()
# Don't build in the top-level or dist directories.
AC_MSG_CHECKING(if building in the top-level or dist directories)
if [ test -d build_unix -o -d aclocal ] ; then
AC_MSG_RESULT(yes)
AC_MSG_ERROR(
[DBSQL should not be built in the top-level or dist directories.])
fi
AC_MSG_RESULT(no)
# Substitution variables.
AC_SUBST(ADDITIONAL_INCS)
AC_SUBST(ADDITIONAL_LANG)
AC_SUBST(ADDITIONAL_OBJS)
AC_SUBST(ADDITIONAL_PROGS)
AC_SUBST(BUILD_TARGET)
AC_SUBST(CFLAGS)
AC_SUBST(CONFIGURATION_ARGS)
AC_SUBST(CONFIGURATION_PATH)
AC_SUBST(CPPFLAGS)
AC_SUBST(CXX)
AC_SUBST(CXXFLAGS)
AC_SUBST(DB_PATH)
AC_SUBST(DB_UNIQUE_NAME)
AC_SUBST(DEFAULT_LIB)
AC_SUBST(DEFAULT_LIB_CXX)
AC_SUBST(ENCODING)
AC_SUBST(INSTALLER)
AC_SUBST(INSTALL_LIBS)
AC_SUBST(INSTALL_TARGET)
AC_SUBST(LDFLAGS)
AC_SUBST(LIBS)
AC_SUBST(LIBSO_LIBS)
AC_SUBST(LIBTOOL)
AC_SUBST(LIBTSO_LIBS)
AC_SUBST(LIBTSO_MODSUFFIX)
AC_SUBST(LIBTSO_MODULE)
AC_SUBST(LIBXSO_LIBS)
AC_SUBST(LOAD_LIBS)
AC_SUBST(MAKEFILE_CC)
AC_SUBST(MAKEFILE_CCLINK)
AC_SUBST(MAKEFILE_CXX)
AC_SUBST(MAKEFILE_CXXLINK)
AC_SUBST(MAKEFILE_SOLINK)
AC_SUBST(MAKEFILE_XSOLINK)
AC_SUBST(OSDIR)
AC_SUBST(PATH_SEPARATOR)
AC_SUBST(POSTLINK)
AC_SUBST(REPLACEMENT_OBJS)
AC_SUBST(RPC_CLIENT_OBJS)
AC_SUBST(RPM_BUILD)
AC_SUBST(RPM_POST_INSTALL)
AC_SUBST(RPM_POST_UNINSTALL)
AC_SUBST(SOFLAGS)
AC_SUBST(o)
# RPM needs the current absolute path.
# RPM needs the list of original arguments, but we don't include the RPM
# option itself.
CONFIGURATION_PATH=${PWD-`pwd`}
CONFIGURATION_ARGS=`echo "$*" | sed -e 's/--with-rpm[[^ ]]*//'`
# Set the default installation location.
AC_PREFIX_DEFAULT(/usr/local/DBSQL.__EDIT_DBSQL_VERSION_MAJOR__.__EDIT_DBSQL_VERSION_MINOR__)
# Configure the version information.
AC_SUBST(DBSQL_VERSION_MAJOR)
DBSQL_VERSION_MAJOR="__EDIT_DBSQL_VERSION_MAJOR__"
AC_SUBST(DBSQL_VERSION_MINOR)
DBSQL_VERSION_MINOR="__EDIT_DBSQL_VERSION_MINOR__"
AC_SUBST(DBSQL_VERSION_PATCH)
DBSQL_VERSION_PATCH="__EDIT_DBSQL_VERSION_PATCH__"
AC_SUBST(DBSQL_VERSION_STRING)
DBSQL_VERSION_STRING='"__EDIT_DBSQL_VERSION_STRING__"'
AC_SUBST(DBSQL_VERSION_UNIQUE_NAME)
# Process all options before using them.
AM_OPTIONS_SET
# Set some #defines based on configuration options.
if test "$db_cv_diagnostic" = "yes"; then
AC_DEFINE(DIAGNOSTIC)
AH_TEMPLATE(DIAGNOSTIC,
[Define to 1 if you want a version with run-time diagnostic checking.])
fi
if test "$db_cv_test" = "yes"; then
AC_DEFINE(CONFIG_TEST)
AH_TEMPLATE(CONFIG_TEST,
[Define to 1 if you want to build a version for running the test suite.])
fi
# Check for programs used in building and installation.
AM_PROGRAMS_SET
AC_PROG_INSTALL
# RPM support: change the standard make and install targets
if test "$db_cv_rpm" = "yes"; then
BUILD_TARGET="rpm_build"
# Check if we are running RPM version 3 or 4.
case "`rpm --version`" in
*version\ 4*)
RPM_BUILD="rpmbuild"
echo "_topdir $CONFIGURATION_PATH" > rpm-macro-defines;;
*version\ 3*)
RPM_BUILD="rpm"
echo "topdir: $CONFIGURATION_PATH" > rpm-macro-defines;;
esac
INSTALL_TARGET="rpm_install"
else
BUILD_TARGET="library_build"
INSTALL_TARGET="library_install"
fi
# This is where we handle stuff that autoconf can't handle: compiler,
# preprocessor and load flags, libraries that the standard tests don't
# look for. The default optimization is -O. We would like to set the
# default optimization for systems using gcc to -O2, but we can't. By
# the time we know we're using gcc, it's too late to set optimization
# flags.
#
# There are additional libraries we need for some compiler/architecture
# combinations.
#
# Some architectures require DB to be compiled with special flags and/or
# libraries for threaded applications
#
# The makefile CC may be different than the CC used in config testing,
# because the makefile CC may be set to use $(LIBTOOL).
#
# XXX
# Don't override anything if it's already set from the environment.
optimize_def="-O"
case "$host_os" in
aix4.3.*|aix5*)
optimize_def="-O2"
CC=${CC-"xlc_r"}
CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
LDFLAGS="$LDFLAGS -Wl,-brtl";;
bsdi3*) optimize_def="-O2"
CC=${CC-"shlicc2"}
LIBS="$LIBS -lipc";;
bsdi*) optimize_def="-O2";;
cygwin*)
optimize_def="-O2"
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
freebsd*)
optimize_def="-O2"
CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
LDFLAGS="$LDFLAGS -pthread";;
gnu*|k*bsd*-gnu|linux*)
optimize_def="-O2"
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
hpux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
irix*) optimize_def="-O2"
CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";;
mpeix*) CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE"
LIBS="$LIBS -lsocket -lsvipc";;
osf*) CPPFLAGS="$CPPFLAGS -pthread";;
*qnx*) AC_DEFINE(HAVE_QNX)
AH_TEMPLATE(HAVE_QNX, [Define to 1 if building on QNX.]);;
solaris*)
CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
esac
# Set CFLAGS/CXXFLAGS. We MUST set the flags before we call autoconf
# compiler configuration macros, because if we don't, they set CFLAGS
# to no optimization and -g, which isn't what we want.
if test "$db_cv_debug" = "no"; then
CFLAGS=${CFLAGS-$optimize_def}
fi
CXXFLAGS=${CXXFLAGS-"$CFLAGS"}
# If the user wants a TCL library interface setup for testing, add
# -DCONFIG_TEST to the CFLAGS value.
if test "$db_cv_test" = "yes"; then
AC_DEFINE(CONFIG_TEST)
AH_TEMPLATE(CONFIG_TEST,
[Define to 1 if you want a TCL API with test support.])
CFLAGS="$CFLAGS -DCONFIG_TEST"
CXXFLAGS="$CXXFLAGS -DCONFIG_TEST"
db_cv_build_tcl_test_objs=TCL_TEST_OBJS
else
db_cv_build_tcl_test_objs=
fi
AC_SUBST(db_cv_build_tcl_test_objs)
# If the user wants a debugging environment, add -g to the CFLAGS value.
#
# XXX
# Some compilers can't mix optimizing and debug flags. The only way to
# handle this is to specify CFLAGS in the environment before configuring.
if test "$db_cv_debug" = "yes"; then
AC_DEFINE(DEBUG)
AH_TEMPLATE(DEBUG, [Define to 1 if you want a debugging version.])
CFLAGS="$CFLAGS -g"
CXXFLAGS="$CXXFLAGS -g"
db_cv_build_type=debug
else
db_cv_build_type=release
fi
AC_SUBST(db_cv_build_type)
# The default compiler is cc (NOT gcc), the default CFLAGS is as specified
# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags
# for any compiler other than gcc.
AC_PROG_CC(cc gcc)
# Checks for compiler characteristics.
AC_SUBST(DB_PROTO1)
AC_SUBST(DB_PROTO2)
# Clear __P, some other systems use it too.
DB_PROTO1="#undef __P"
if test "$ac_cv_prog_cc_c89" = "no"; then
DB_PROTO2="#define __P(protos) ()"
else
DB_PROTO2="#define __P(protos) protos"
fi
# Check for "const" and "inline" keywords.
AC_C_CONST
AC_SUBST(DB_CONST)
if test "$ac_cv_c_const" != "yes"; then
DB_CONST="#define const"
fi
AC_C_INLINE
# Because of shared library building, the ${CC} used for config tests
# may be different than the ${CC} we want to put in the Makefile.
# The latter is known as ${MAKEFILE_CC} in this script.
MAKEFILE_CC="${CC}"
MAKEFILE_CCLINK="${CC}"
MAKEFILE_CXX="nocxx"
MAKEFILE_CXXLINK="nocxx"
# See if we need the C++ compiler at all. If so, we'd like to find one that
# interoperates with the C compiler we chose. Since we prefered cc over gcc,
# we'll also prefer the vendor's compiler over g++/gcc. If we're wrong, the
# user can set CC and CXX in their environment before running configure.
#
# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its
# first choices.
if test "$db_cv_cxx" = "yes"; then
if test "$GCC" != "yes"; then
case "$host_os" in
aix*) AC_CHECK_TOOL(CCC, xlC_r)
LIBXSO_LIBS="-lC_r $LIBXSO_LIBS"
LIBS="-lC_r $LIBS";;
hpux*) AC_CHECK_TOOL(CCC, aCC);;
irix*) AC_CHECK_TOOL(CCC, CC);;
osf*) AC_CHECK_TOOL(CCC, cxx);;
solaris*) AC_CHECK_TOOL(CCC, CC);;
esac
fi
AC_PROG_CXX
###### WORKAROUND: SEE SR #7938
AC_PROG_CXXCPP
###############################
AC_CXX_STDHEADERS
MAKEFILE_CXX="${CXX}"
MAKEFILE_CXXLINK="${CXX}"
fi
# Do some gcc specific configuration.
AC_GCC_CONFIG1
# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare
# and OpenUNIX releases. We can't make the test until we know which compiler
# we're using.
case "$host_os" in
sysv5UnixWare*|sysv5OpenUNIX8*)
if test "$GCC" == "yes"; then
CPPFLAGS="$CPPFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
else
CPPFLAGS="$CPPFLAGS -Kthread"
LDFLAGS="$LDFLAGS -Kthread"
fi;;
esac
# Export our compiler preferences for the libtool configuration.
export CC CCC
CCC=CXX
# Libtool configuration.
LT_INIT
AC_SUBST([LIBTOOL_DEPS])
SOFLAGS="-rpath \$(libdir)"
LIBTOOL_PROG="${SHELL} ./libtool"
# Set SOSUFFIX and friends
SOSUFFIX_CONFIG
MODSUFFIX_CONFIG
INSTALLER="\$(LIBTOOL) --mode=install cp -p"
MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}"
MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version"
MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}"
MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}"
MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}"
LIBTOOL="\$(SHELL) ./libtool"
case "$host_os" in
cygwin*)
MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined"
MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";;
esac
# Configure for shared libraries, static libraries, or both. If both are
# configured, build the utilities and example programs with shared versions.
#
# $o is set to ".o" or ".lo", and is the file suffix used in the Makefile
# instead of .o
if test `$LIBTOOL_PROG --config |
grep build_libtool_libs | grep no` 2>/dev/null; then
enable_shared="no"
else
enable_shared="yes"
fi
if test `$LIBTOOL_PROG --config |
grep build_old_libs | grep no` 2>/dev/null; then
enable_static="no"
else
enable_static="yes"
fi
# C API.
if test "$enable_shared" = "no"; then
DEFAULT_LIB="\$(libdb_version)"
POSTLINK=": "
o=".o"
else
DEFAULT_LIB="\$(libso_target)"
POSTLINK="\$(LIBTOOL) --mode=execute true"
o=".lo"
fi
INSTALL_LIBS="$DEFAULT_LIB"
if test "$enable_static" = "yes"; then
INSTALL_LIBS="$INSTALL_LIBS \$(libdb)"
fi
# Optional C++ API.
if test "$db_cv_cxx" = "yes"; then
if test "$enable_shared" = "no"; then
DEFAULT_LIB_CXX="\$(libcxx_version)"
fi
if test "$enable_shared" = "yes"; then
DEFAULT_LIB_CXX="\$(libxso_target)"
fi
INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX"
if test "$enable_static" = "yes"; then
INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)"
fi
fi
dnl # Optional Java API. TODO
# MinGW support.
if test "$db_cv_mingw" = "yes"; then
OSDIR=os_win32
PATH_SEPARATOR="\\\\/:"
AC_DEFINE(DBSQL_WIN32)
AC_DEFINE(STDC_HEADERS)
else
OSDIR=os
PATH_SEPARATOR="/"
fi
# Apple's Mac OS/X had to rename shared libraries, so much for standards.
case "$host_os" in
darwin*)
LIBTSO_MODULE=""
LIBTSO_MODSUFFIX=".dylib"
;;
*)
LIBTSO_MODULE="-module"
LIBTSO_MODSUFFIX=@MODSUFFIX@
;;
esac
AM_TCL_LOAD
# You can disable pieces of functionality to save space.
# The stat code.
if test "$db_cv_build_statistics" = "yes"; then
AC_DEFINE(HAVE_STATISTICS)
AH_TEMPLATE(HAVE_STATISTICS,
[Define to 1 if building statistics support.])
fi
# Checks for include files, structures, C types.
AC_HEADER_STAT
AC_CHECK_HEADERS_ONCE([sys/time.h])
# End of obsolete code.
AC_HEADER_DIRENT
AC_CHECK_HEADERS(sys/select.h sys/time.h sys/fcntl.h)
AC_CHECK_MEMBERS([struct stat.st_blksize])
AM_TYPES
AC_CACHE_CHECK([for ANSI C exit success/failure values], db_cv_exit_defines, [
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[[#include <stdlib.h>]],
[[return (EXIT_SUCCESS);]])],
[db_cv_exit_defines=yes],[db_cv_exit_defines=no])])
if test "$db_cv_exit_defines" = "yes"; then
AC_DEFINE(HAVE_EXIT_SUCCESS)
AH_TEMPLATE(HAVE_EXIT_SUCCESS,
[Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines.])
fi
# Test for various functions/libraries that the test and example programs use:
# sched_yield function
# pthreads, socket and math libraries
AC_CHECK_FUNC(sched_yield,,
AC_SEARCH_LIBS(sched_yield, rt, LOAD_LIBS="$LOAD_LIBS -lrt"))
# XXX
# We can't check for pthreads in the same way we did the test for sched_yield
# because the Solaris C library includes pthread interfaces which are not
# thread-safe. For that reason we always add -lpthread if we find a pthread
# library. Also we can't depend on any specific call existing (pthread_create,
# for example), as it may be #defined in an include file -- OSF/1 (Tru64) has
# this problem.
AC_CHECK_LIB([pthread],[main],[LOAD_LIBS="$LOAD_LIBS -lpthread"],[],[])ac_cv_lib_pthread=ac_cv_lib_pthread_main
# We use sqrt() so we need the math library -lm
AC_CHECK_LIB([m],[main],[LIBS="$LIBS -lm"],[],[])ac_cv_lib_m=ac_cv_lib_m_main
# Checks for system functions for which we have replacements.
AC_REPLACE_FUNCS(getopt memcmp memcpy memmove strdup strndup strerror)
AC_REPLACE_FUNCS(snprintf localtime_r strcasecmp strncasecmp)
AC_REPLACE_FUNCS(srand48_r lrand48_r)
# Check for system functions we use.
AC_CHECK_FUNCS(usleep)
# A/UX has a broken getopt(3).
case "$host_os" in
aux*) AC_LIBOBJ([getopt]);;
esac
# Apple's Mac OS/X complains about long doubles, make it stop.
case "$host_os" in
darwin*)
CFLAGS="$CFLAGS -Wno-long-double -no-cpp-precomp"
;;
esac
# We need to add the additional object files into the Makefile with the correct
# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded
# in it for automake, and that's not what we want.
REPLACEMENT_OBJS=`echo "$LIB@&t@OBJS" |
sed "s,\.[[^.]]* ,$o ,g;s,\.[[^.]]*$,$o,"`
# This is necessary so that .o files in LIBOBJS are also built via
# the ANSI2KNR-filtering rules.
LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
LTLIBOBJS=`echo "$LIB@&t@OBJS" |
sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
AC_SUBST(LTLIBOBJS)
# Initial output file list.
CREATE_LIST="Makefile
dbsql_int.h:$srcdir/../src/inc/dbsql_int.in
$srcdir/../src/py/setup.py:$srcdir/../src/py/setup.py.in
$srcdir/../test/scr050/Makefile:$srcdir/../test/scr050/Makefile.in"
# MinGW needs win_db.h.
if test "$db_cv_mingw" = "yes"; then
CREATE_LIST="$CREATE_LIST
win_db.h:$srcdir/win_dbsql.in"
fi
# Create the dbsql.h file from a source file and a list of global function
# prototypes.
CREATE_LIST="$CREATE_LIST
dbsql.h:$srcdir/../src/dbsql.in"
if test "$db_cv_rpm" = "yes"; then
CREATE_LIST="$CREATE_LIST db.spec:../dist/dbsql.spec.in"
fi
AC_CONFIG_FILES($CREATE_LIST)
AC_OUTPUT

31
dist/dbsql.pc.in vendored
View file

@ -1,31 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Package Information for pkg-config
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: dbsql
Description: A SQL database engine.
Version: @VERSION@
Libs: -L${libdir} -ldbsql -ldb
Cflags: -I${includedir}

53
dist/dbsql.spec.in vendored
View file

@ -1,53 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# DBSQL @DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@.@DBSQL_VERSION_PATCH@
Summary: DBSQL - A SQL database library.
Name: dbsql
Version: @DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@.@DBSQL_VERSION_PATCH@
Release: 1
Copyright: GPL - Freely redistributable, see LICENSE for details.
Source: http://www.dbsql.org/update/@DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@.@DBSQL_VERSION_PATCH@/dbsql-@DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@.@DBSQL_VERSION_PATCH@.tar.gz
URL: http://www.dbsql.org
Group: System Environment/Libraries
BuildRoot: @CONFIGURATION_PATH@/RPM_INSTALL
%define _unpackaged_files_terminate_build 0
%description
DBSQL is a programmatic toolkit that provides fast, scalable and
reliable SQL implementation.
%prep
%setup
%build
cd build_unix
CFLAGS="$RPM_OPT_FLAGS" ../dist/configure @CONFIGURATION_ARGS@
make library_build
%install
cd build_unix
make prefix=@CONFIGURATION_PATH@/RPM_INSTALL install
@RPM_POST_INSTALL@
@RPM_POST_UNINSTALL@
%changelog

39
dist/dot-gdbinit vendored
View file

@ -1,39 +0,0 @@
break __db_loadme
break __db_err
define dd
print __db_dump(dbp, "a", "/tmp/o")
end
define dc
print __db_dump(dbc->dbp, "a", "/tmp/o")
end
break __sm_create
break __sm_create_table
break __sm_create_index
break __sm_close_db
break __sm_checkpoint
break __sm_get_database_name
break __sm_begin_txn
break __sm_commit_txn
break __sm_abort_txn
break __sm_cursor
break __sm_close_cursor
break __sm_moveto
break __sm_next
break __sm_prev
break __sm_key_size
break __sm_data_size
break __sm_key_compare
break __sm_key
break __sm_data
break __sm_first
break __sm_last
break __sm_insert
break __sm_delete
break __sm_drop_table
break __sm_clear_table
break __sm_set_format_version
break __sm_get_format_version
break __sm_set_schema_sig
break __sm_get_schema_sig
break process_input
break __process_sql

80
dist/gen_inc.awk vendored
View file

@ -1,80 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
# This awk script parses C input files looking for lines marked "PUBLIC:"
# and "EXTERN:". (PUBLIC lines are DB internal function prototypes and
# #defines, EXTERN are DB external function prototypes and #defines.)
#
# PUBLIC lines are put into two versions of per-directory include files:
# one file that contains the prototypes, and one file that contains a
# #define for the name to be processed during configuration when creating
# unique names for every global symbol in the DB library.
#
# The EXTERN lines are put into two files: one of which contains prototypes
# which are always appended to the db.h file, and one of which contains a
# #define list for use when creating unique symbol names.
#
# Four arguments:
# e_dfile list of EXTERN #defines
# e_pfile include file that contains EXTERN prototypes
# i_dfile list of internal (PUBLIC) #defines
# i_pfile include file that contains internal (PUBLIC) prototypes
# i_sfile include file that contains internal (STATIC) prototypes
/PUBLIC:/ {
sub("^.*PUBLIC:[ ][ ]*", "")
if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") {
print $0 >> i_pfile
print $0 >> i_dfile
next
}
pline = sprintf("%s %s", pline, $0)
if (pline ~ "\\)\\);") {
sub("^[ ]*", "", pline)
print pline >> i_pfile
pline = ""
}
}
/STATIC:/ {
sub("^.*STATIC:[ ][ ]*", "")
if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") {
print $0 >> i_sfile
next
}
sline = sprintf("%s %s", sline, $0)
if (sline ~ "\\)\\);") {
sub("^[ ]*", "", sline)
print sline >> i_sfile
sline = ""
}
}
/EXTERN:/ {
sub("^.*EXTERN:[ ][ ]*", "")
if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") {
print $0 >> e_pfile
print $0 >> e_dfile
next
}
eline = sprintf("%s %s", eline, $0)
if (eline ~ "\\)\\);") {
sub("^[ ]*", "", eline)
print eline >> e_pfile
eline = ""
}
}

541
dist/install-sh vendored
View file

@ -1,541 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-p pass -p to $cpprog.
-s $stripprog installed files.
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.
If -S is not specified, no backups are attempted.
Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
-S) backupsuffix="$2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
# Don't chown directories that already exist.
if test $dstdir_status = 0; then
chowncmd=""
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# If $backupsuffix is set, and the file being installed
# already exists, attempt a backup. Don't worry if it fails,
# e.g., if mv doesn't support -f.
if test -n "$backupsuffix" && test -f "$dst"; then
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
fi
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

11436
dist/ltmain.sh vendored

File diff suppressed because it is too large Load diff

0
dist/pubdef.in vendored
View file

29
dist/s_all vendored
View file

@ -1,29 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
sh s_perm # permissions.
sh s_symlink # symbolic links.
sh s_readme # distribution README file.
#
# The following order is important, s_include must run last.
#
sh s_config # autoconf.
sh s_include # standard include files.
sh s_tags # Tags files.

50
dist/s_config vendored
View file

@ -1,50 +0,0 @@
#!/bin/sh -x
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build the autoconfiguration files.
trap 'rm -f aclocal.m4 ; exit 0' 0 1 2 3 13 15
. ./RELEASE
echo "autoconf: building aclocal.m4..."
cat aclocal/*.m4 > aclocal.m4
echo "autoconf: running autoheader to build config.hin..."
rm -f config.hin
autoheader --warnings=all
chmod 444 config.hin
echo "autoconf: running autoconf to build configure"
rm -f configure
autoconf
# Edit version information we couldn't pre-compute.
(echo "1,\$s/__EDIT_DBSQL_VERSION_MAJOR__/$DBSQL_VERSION_MAJOR/g" &&
echo "1,\$s/__EDIT_DBSQL_VERSION_MINOR__/$DBSQL_VERSION_MINOR/g" &&
echo "1,\$s/__EDIT_DBSQL_VERSION_PATCH__/$DBSQL_VERSION_PATCH/g" &&
echo "1,\$s/__EDIT_DBSQL_VERSION_STRING__/$DBSQL_VERSION_STRING/g" &&
echo "1,\$s/__EDIT_DBSQL_VERSION__/$DBSQL_VERSION/g" &&
echo "w" &&
echo "q") | ed -s configure
rm -rf autom4te.cache
chmod 555 configure
chmod 555 config.guess config.sub install-sh

111
dist/s_include vendored
View file

@ -1,111 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build the automatically generated function prototype files.
msgc="/* DO NOT EDIT: automatically built by dist/s_include. */"
head()
{
defonly=0
while :
do case "$1" in
space)
echo ""; shift;;
defonly)
defonly=1; shift;;
*)
name="$1"; break;;
esac
done
echo "$msgc"
echo "#ifndef $name"
echo "#define $name"
echo ""
if [ $defonly -eq 0 ]; then
echo "#if defined(__cplusplus)"
echo "extern \"C\" {"
echo "#endif"
echo ""
fi
}
tail()
{
defonly=0
while :
do case "$1" in
defonly)
defonly=1; shift;;
*)
name="$1"; break;;
esac
done
echo ""
if [ $defonly -eq 0 ]; then
echo "#if defined(__cplusplus)"
echo "}"
echo "#endif"
fi
echo "#endif /* !$name */"
}
# We are building several files:
# 1 external #define file
# 1 external prototype file
# 1 internal #define file
# N internal prototype files
e_dfile=/tmp/__db_c.$$
e_pfile=/tmp/__db_a.$$
i_dfile=/tmp/__db_d.$$
i_pfile=/tmp/__db_b.$$
i_sfile=/tmp/__db_e.$$
trap 'rm -f $e_dfile $e_pfile $i_dfile $i_pfile $i_sfile; exit 0' 0 1 2 3 13 15
head defonly space _DBSQL_EXT_DEF_IN_ > $e_dfile
head space _DBSQL_EXT_PROT_IN_ > $e_pfile
head defonly _DBSQL_INT_DEF_IN_ > $i_dfile
# Process the standard directories, creating per-directory prototype
# files and adding to the external prototype and #define files.
for pkg in dbsql os clib common ; do
head "_${pkg}_ext_h_" > $i_pfile
cfiles="../src/${pkg}/*.c"
[ "$cfiles" = "../src/dbsql/*.c" ] && cfiles="../src/*.c"
for file in $(ls $cfiles); do
fname="$(echo $file | sed -n 's/^\(.*\/\)*\([^.]*\)\(.*\)/\2/p')"
head "_${fname}_decl_h_" > $i_sfile
awk -f gen_inc.awk \
-v e_dfile=$e_dfile \
-v e_pfile=$e_pfile \
-v i_dfile=$i_dfile \
-v i_pfile=$i_pfile \
-v i_sfile=$i_sfile $file
tail "_${fname}_decl_h_" >> $i_sfile
decl="../src/inc/${fname}_decl.h"
# cmp $i_sfile $decl > /dev/null 2>&1 ||
# (echo "Building $decl" && rm -f $decl && cp $i_sfile $decl && chmod 444 $decl)
done
tail "_${pkg}_ext_h_" >> $i_pfile
ext="../src/inc/${pkg}_ext.h"
cmp $i_pfile $ext > /dev/null 2>&1 ||
(echo "Building $ext" && rm -f $ext && cp $i_pfile $ext && chmod 444 $ext)
done

45
dist/s_perm vendored
View file

@ -1,45 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
d=..
echo 'Updating DBSQL source tree permissions...'
run()
{
#echo " $1 ($2)"
if [ -f "$d/$1" ]; then
chmod "$2" "$d/$1"
else
echo "$d/$1: no such file or directory"
exit 1
fi
}
run dist/config.guess 555
run dist/config.sub 555
run dist/configure 555
run dist/install-sh 555
run dist/s_all 555
run dist/s_config 555
run dist/s_include 555
run dist/s_perm 555
run dist/s_readme 555
run dist/s_symlink 555
run dist/s_tags 555
run dist/s_test 555

82
dist/s_readme vendored
View file

@ -1,82 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build the README.
echo 'Updating DBSQL README file...'
d=..
t=/tmp/__t
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
. ./RELEASE
cat << END_OF_README>$t
$DBSQL_VERSION_STRING
This is version $DBSQL_VERSION_MAJOR.$DBSQL_VERSION_MINOR.$DBSQL_VERSION_PATCH of DBSQL.
To view the release and installation documentation, load the distribution
file docs/index.html into your web browser.
This work started from the SQLite project (found on the web at
http://www.sqlite.org/). SQLite and all contributions to the SQLite
project have been placed in the public domain by its author, Dr. Richard Hipp.
There was no assertion of copyright at all on the code I used as a starting
point for my work. In fact there are statements that explicitly disclaim
copyright. I am asserting copyright on this work, DBSQL. I believe
that if you examine the extent to which I've changed, updated, and
modified the SQLite code you'll respect my copyright assertion. This
is a new product, heavily inspired by another.
The goal for DBSQL is to provide a small SQL92 relational database layer
on top of the Berkeley DB database. Berkeley DB is copyright Oracle
Corporation (formerly Sleepycat Software, acquired in Feb 2006) and
licensed under the Sleepycat Public License. That license is compatible
with the GPL for open source use. Recognize that you, as someone using
DBSQL, will need to review the Sleepycat License and the GPL before you
use and redistribute your incorporating work. It is your responsibility
to comply with those licenses as I am in my work on DBSQL itself. My
motivation on a personal level is quite simple, I am in product management
these days and not in the code itself. I believe that product managers
should be engineers at heart with an ability to understand business,
politics, and software sales and support. This is my playground to keep
my engineering skills sharp enough to speak fluent geek. As a former
engineer at Sleepycat I understand and value the Berkeley DB programming
infrasture, design, and methodologies and I have liberally copied and
reused them in this project to improve SQLite in ways that I hope will
be of value to open source users out there. I did this because I see the
value of SQLite to its userbase, it is a perfect example of the 80/20
rule and the KISS method and I admire those qualities in software. My
hope is that the Berkeley DB database engine will provide some significant
features that SQLite cannot such as replication for high availability
while remaining small enough to live comfortably inside applications,
services, and devices.
Information and resources pertaining to DBSQL can be found at dbsql.org.
Commercial licenses without the restrictions found in the GPL can be
purchased for this product. See http://dbsql.org/wiki/CommercialUse
END_OF_README
f=../README
cmp $t $f > /dev/null 2>&1 ||
(echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f)

40
dist/s_symlink vendored
View file

@ -1,40 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
echo 'Creating DBSQL source tree symbolic links...'
build()
{
#echo " $1 -> $2"
(cd ../`dirname $1` && rm -f `basename $1` && ln -s $2 `basename $1`)
}
build src/tags ../dist/tags
build src/os/tags ../../dist/tags
build src/clib/tags ../../dist/tags
build src/py/tags ../../dist/tags
build test/scr050/tags ../../dist/tags
build build_unix/tags ../dist/tags
build src/TAGS ../dist/TAGS
build src/os/TAGS ../../dist/TAGS
build src/clib/TAGS ../../dist/TAGS
build src/py/TAGS ../../dist/TAGS
build test/scr050/TAGS ../../dist/tags
build build_unix/TAGS ../dist/TAGS

48
dist/s_tags vendored
View file

@ -1,48 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build tags files.
files=`echo ../src/*.[ch] \
../src/inc/*.h \
../src/os/*.[ch] \
../src/py/*.[ch] \
../test/scr050/*.[ch]`
f=tags
echo "Building $f"
rm -f $f
# Figure out what flags this ctags accepts.
flags=""
if ctags -d ../src/api.c 2>/dev/null; then
flags="-d $flags"
fi
if ctags -t ../src/api.c 2>/dev/null; then
flags="-t $flags"
fi
if ctags -w ../src/api.c 2>/dev/null; then
flags="-w $flags"
fi
ctags $flags $files 2>/dev/null
chmod 444 $f
etags $files -o TAGS 2>/dev/null
chmod 444 $f

104
dist/s_test vendored
View file

@ -1,104 +0,0 @@
#!/bin/sh -
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
#
# Build the Tcl test files.
msg1="# Automatically built by dist/s_test; may require local editing."
msg2="# Automatically built by dist/s_test; may require local editing."
t=/tmp/__t
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
. RELEASE
(echo "$msg1" && \
echo "" && \
echo "set tclsh_path @TCL_TCLSH@" && \
echo "set tcllib .libs/libdbsql_tcl-@DBSQL_VERSION_MAJOR@.@DBSQL_VERSION_MINOR@@LIBTSO_MODSUFFIX@" && \
echo "" && \
echo "set src_root @srcdir@/.." && \
echo "set test_path @srcdir@/../test" && \
echo "" && \
echo "global testdir" && \
echo "set testdir ./TESTDIR" && \
echo "" && \
echo "global dict" && \
echo "global util_path" && \
echo "" && \
echo "global is_hp_test" && \
echo "global is_qnx_test" && \
echo "global is_windows_test" && \
echo "" && \
echo "set KILL \"@db_cv_path_kill@\"") > $t
f=../test/include.tcl
cmp $t $f > /dev/null 2>&1 ||
(echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f)
(echo "$msg1" && \
echo "" && \
echo "set tclsh_path SET_YOUR_TCLSH_PATH" && \
echo "set tcllib ./Debug/libdbsql_tcl${DBSQL_VERSION_MAJOR}${DBSQL_VERSION_MINOR}d.dll" && \
echo "" && \
echo "set src_root .." && \
echo "set test_path ../test" && \
echo "" && \
echo "global testdir" && \
echo "set testdir ./TESTDIR" && \
echo "" && \
echo "global dict" && \
echo "global util_path" && \
echo "" && \
echo "global is_hp_test" && \
echo "global is_qnx_test" && \
echo "global is_windows_test" && \
echo "" && \
echo "set KILL ./dbkill.exe") > $t
f=../build_win32/include.tcl
cmp $t $f > /dev/null 2>&1 ||
(echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f)
# Build the test directory TESTS file.
(echo $msg2;
cat `egrep -l '^#[ ][ ]*TEST' ../test/*.tcl` |
sed -e '/^#[ ][ ]*TEST/!{' \
-e 's/.*//' \
-e '}' |
cat -s |
sed -e '/TEST/{' \
-e 's/^#[ ][ ]*TEST[ ]*//' \
-e 's/^ //' \
-e 'H' \
-e 'd' \
-e '}' \
-e 's/.*//' \
-e x \
-e 's/\n/__LINEBREAK__/g' |
sort |
sed -e 's/__LINEBREAK__/\
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\
/' \
-e 's/__LINEBREAK__/\
/g' |
sed -e 's/^[ ][ ]*$//') > $t
f=../test/TESTS
cmp $t $f > /dev/null 2>&1 ||
(echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f)

5
dist/splint.rc vendored
View file

@ -1,5 +0,0 @@
-namechecks
+posixstrictlib
+showallconjs
+showscan
+stats

74
dist/sqlconf vendored
View file

@ -1,74 +0,0 @@
#!/bin/sh -
#
# This is how I normally configure DBSQL when I'm doing daily work.
#
# Note that I'm usually using the latest copy of Mac OS/X for
# devlelopment work, so some of this may be specific to that.
#
[ -d build_unix ] && {
echo 'You cannot build in the top-level directory.'
exit 1
}
[ -d aclocal ] && {
echo 'You cannot build in the dist directory.'
exit 1
}
args=""
#args="--disable-shared $args"
#args="--disable-static $args"
args="--enable-vacuum $args"
#args="--enable-datetime $args"
args="--enable-authentication $args"
args="--enable-incore-databases $args"
args="--enable-incore-temp-databases $args"
args="--enable-debug $args"
args="--enable-diagnostic $args"
args="--enable-test $args"
args="--enable-tcl $args"
#args="--enable-sqlite-compat $args"
args="--enable-soundex-sqlfn $args"
#args="--with-tcl=/usr/lib/tcl-8.5.19/lib $args"
#args="--with-berkeleydb=/usr/local/db-4.8.30 $args"
#args="--with-db-uniquename=FOO $args"
# Mac OS/X enable:
#args="LD_TWOLEVEL_NAMESPACE=1 LIBTSO_LIBS=-ltcl8.4 $args"
# On NixOS enable:
CFLAGS="${NIX_CFLAGS_COMPILE} -O0 -g -DDEBUG"
LDLAGS="${NIX_LDFLAGS} /home/gburd/src/libdb/build_unix/.libs"
#args="--with-berkeleydb=$(pkg-config --variable=prefix db) $args"
#args="--with-berkeleydb=/nix/store/mlhib3c2ra8bj36vhxmwqhyxph8a8sgf-db-4.8.30 $args"
args="--with-berkeleydb=/home/gburd/opt $args"
args="--with-tcl=$(pkg-config --variable=libdir tcl) $args"
echo "env $cppflags $ldflags $libs ../dist/configure $args"
env $cppflags $ldflags $libs sh ../dist/configure -C $args
# (echo "break __db_loadme" &&
# echo "break __db_err" &&
# echo "define dd" &&
# echo 'print __db_dump(dbp, "a", "/tmp/o")' &&
# echo "end" &&
# echo "define dc" &&
# echo 'print __db_dump(dbc->dbp, "a", "/tmp/o")' &&
# echo "end") > .gdbinit
# (echo "set environment LD_LIBRARY_PATH=.:.libs" &&
# echo "dir ../src" &&
# echo "dir ../src/dbsql" &&
# echo "dir ../src/dbsql/rl/src" &&
# echo "dir /usr/local/db/src/dist" &&
# echo "path /usr/local/db/lib" &&
# echo "path .") > .gdbinit
rm -f tags
ln -s ../dist/tags tags
mkdir -p .libs && true
exit 0
nix-build -E 'with import <nixpkgs> {}; enableDebugging db4'
gdb -ix .gdbinit --tui build_unix/.libs/dbsql
r --init ../test/smoke.sql smoke

83
dist/srcfiles.in vendored
View file

@ -1,83 +0,0 @@
# DBSQL - A SQL database engine.
#
# Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
#
# This library is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# There are special exceptions to the terms and conditions of the GPL as it
# is applied to this software. View the full text of the exception in file
# LICENSE_EXCEPTIONS in the directory of this software distribution.
#
# 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
# General Public License for more details.
# This is an input file for the s_win32_dsp. It lists the source files in
# the DBSQL tree and notes which are used to build the Win/32 library.
#
# Please keep this list sorted alphabetically!
#
# Each non-blank, non-comment line is of the form
# filename module [ module ...]
#
# The possible modules, including the name of the project (.dsp) file:
#
# app=NAME Linked into application NAME.exe (db_NAME.dsp)
# dynamic File is in the Windows DLL (db_dll.dsp)
# static File is in the Windows static library (db_static.dsp)
# java File is in the Windows Java DLL (db_java.dsp)
# tcl File is in the Windows tcl DLL (db_tcl.dsp)
# testutil File is used for Windows testing (db_test.dsp)
build_unix/lempar.c dynamic static
build_unix/opcodes.c dynamic static
build_unix/sql_parser.c dynamic static
build_win32/dbkill.cpp testutil
dist/splint.rc
examples/binary_codec.c
src/api.c dynamic static
src/api_table.c dynamic static
src/cg_attach.c dynamic static
src/cg_auth.c dynamic static
src/cg_build.c dynamic static
src/cg_copy.c dynamic static
src/cg_date.c dynamic static
src/cg_delete.c dynamic static
src/cg_expr.c dynamic static
src/cg_insert.c dynamic static
src/cg_pragma.c dynamic static
src/cg_select.c dynamic static
src/cg_trigger.c dynamic static
src/cg_update.c dynamic static
src/cg_vacuum.c dynamic static
src/cg_where.c dynamic static
src/clib/getopt.c app=dbsql
src/clib/memcmp.c dynamic static
src/clib/random.c dynamic static
src/clib/snprintf.c dynamic static
src/clib/strcasecmp.c dynamic static
src/clib/strdup.c dynamic static
src/clib/xvprintf.c dynamic static
src/common/dbsql_alloc.c dynamic static
src/common/dbsql_atof.c dynamic static
src/common/dbsql_atoi.c dynamic static
src/common/dbsql_err.c dynamic static
src/common/hash.c dynamic static
src/common/str.c dynamic static
src/dbsql/dbsql.c app=dbsql
src/dbsql_tclsh.c app=dbsql_tclsh
src/lemon/lemon.c app=lemon
src/lemon/lempar.c app=lemon
src/os/os_jtime.c dynamic static
src/os/os_sleep.c dynamic static
src/safety.c dynamic static
src/sm.c dynamic static
src/sql_fns.c dynamic static
src/sql_tokenize.c dynamic static
src/vdbe.c dynamic static
src/vdbe_method.c dynamic static

View file

@ -1,203 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH DBSQL 1 "Mon Apr 15 23:49:17 2002"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
dbsql \- A command line interface for DBSQL
.SH SYNOPSIS
.B dbsql
.RI [ options ] " filename " [ SQL ]
.SS SUMMARY
.PP
dbsql is a terminal-based front-end to the DBSQL library. It enables
you to type in queries interactively, issue them to DBSQL and see the
results. Alternatively, you can specify SQL code on the command-line. In
addition it provides a number of meta-commands.
.SH DESCRIPTION
This manual page documents briefly the
.B dbsql
command.
This manual page was written for the Debian GNU/Linux distribution
because the original program does not have a manual page.
.SS GETTING STARTED
.PP
To start the dbsql program, just type "dbsql" followed by the name
the file that holds the DBSQL database. If the file does not exist, a
new one is created automatically. The dbsql program will then prompt
you to enter SQL. Type in SQL statements (terminated by a semicolon),
press "Enter" and the SQL will be executed.
For example, to create a new DBSQL database named "ex1" with a single
table named "tbl1", you might do this:
.sp
.nf
$ dbsql ex1
DBSQL version 2.0.0
Enter ".help" for instructions
dbsql> create table tbl1(one varchar(10), two smallint);
dbsql> insert into tbl1 values('hello!',10);
dbsql> insert into tbl1 values('goodbye', 20);
dbsql> select * from tbl1;
hello!|10
goodbye|20
dbsql>
.sp
.fi
.SS DBSQL META-COMMANDS
.PP
Most of the time, dbsql just reads lines of input and passes them on
to the DBSQL library for execution. But if an input line begins with
a dot ("."), then that line is intercepted and interpreted by the
dbsql program itself. These "dot commands" are typically used to
change the output format of queries, or to execute certain prepackaged
query statements.
For a listing of the available dot commands, you can enter ".help" at
any time. For example:
.sp
.nf
.cc |
dbsql> .help
.dump ?TABLE? ... Dump the database in an text format
.echo ON|OFF Turn command echo on or off
.exit Exit this program
.explain ON|OFF Turn output mode suitable for EXPLAIN on or off.
"off" will revert to the output mode that was
previously in effect
.header(s) ON|OFF Turn display of headers on or off
.help Show this message
.indices TABLE Show names of all indices on TABLE
.mode MODE Set mode to one of "line(s)", "column(s)",
"insert", "list", or "html"
.mode insert TABLE Generate SQL insert statements for TABLE
.nullvalue STRING Print STRING instead of nothing for NULL data
.output FILENAME Send output to FILENAME
.output stdout Send output to the screen
.prompt MAIN CONTINUE Replace the standard prompts
"dbsql > " and " ...> "
with the strings MAIN and CONTINUE
CONTINUE is optional.
.quit Exit this program
.read FILENAME Execute SQL in FILENAME
.reindex ?TABLE? Rebuild indices
.schema ?TABLE? Show the CREATE statements
.separator STRING Change separator string for "list" mode
.show Show the current values for the following:
.echo
.explain
.mode
.nullvalue
.output
.separator
.width
.tables ?PATTERN? List names of tables matching a pattern
.timeout MS Try opening locked tables for MS milliseconds
.width NUM NUM ... Set column widths for "column" mode
dbsql>
|cc .
.sp
.fi
.SH OPTIONS
The program has the following options:
.TP
.BI \-init\ file
Read in and process 'file', which contains "dot commands".
You can use this file to initialize display settings.
.TP
.B \-html
Set output mode to HTML.
.TP
.B \-list
Set output mode to 'list'.
.TP
.B \-line
Set output mode to 'line'.
.TP
.B \-column
Set output mode to 'column'.
.TP
.BI \-separator\ separator
Specify which output field separator for 'list' mode to use.
Default is '|'.
.TP
.BI \-nullvalue\ string
When a null is encountered, print 'string'. Default is no string.
.TP
.B \-[no]header
Turn headers on or off. Default is off.
.TP
.B \-echo
Print commands before execution.
.SH OUTPUT MODE
The DBSQL program has different output modes, which define the way
the output (from queries) is formatted.
In 'list' mode, which is the default, one record per line is output,
each field separated by the separator specified with the
\fB-separator\fP option or \fB.separator\fP command.
In 'line' mode, each column is output on its own line, records are
separated by blank lines.
In HTML mode, an XHTML table is generated.
In 'column' mode, one record per line is output, aligned neatly in colums.
.SH INIT FILE
dbsql can be initialized using resource files. These can be combined with
command line arguments to set up dbsql exactly the way you want it.
Initialization proceeds as follows:
o The defaults of
.sp
.nf
.cc |
mode = LIST
separator = "|"
main prompt = "dbsql> "
continue prompt = " ...> "
|cc .
.sp
.fi
are established.
o If a file .dbsqlrc can be found in the user's home directory, it is
read and processed. It should only contain "dot commands". If the
file is not found or cannot be read, processing continues without
notification.
o If a file is specified on the command line with the -init option, it
is processed in the same manner as .dbsqlrc
o All other command line options are processed
o The database is opened and you are now ready to begin.
.SH SEE ALSO
http://dbsql.org/
.br
The dbsql-doc package
.SH AUTHOR
This manual page was originally written by Andreas Rottmann
<rotty@debian.org>, for the Debian GNU/Linux system (but may be used
by others).

View file

@ -1,892 +0,0 @@
<html>
<head>
<title>The Lemon Parser Generator</title>
</head>
<body bgcolor=white>
<h1 align=center>The Lemon Parser Generator</h1>
<p>Lemon is an LALR(1) parser generator for C or C++.
It does the same job as ``bison'' and ``yacc''.
But lemon is not another bison or yacc clone. It
uses a different grammar syntax which is designed to
reduce the number of coding errors. Lemon also uses a more
sophisticated parsing engine that is faster than yacc and
bison and which is both reentrant and thread-safe.
Furthermore, Lemon implements features that can be used
to eliminate resource leaks, making is suitable for use
in long-running programs such as graphical user interfaces
or embedded controllers.</p>
<p>This document is an introduction to the Lemon
parser generator.</p>
<h2>Theory of Operation</h2>
<p>The main goal of Lemon is to translate a context free grammar (CFG)
for a particular language into C code that implements a parser for
that language.
The program has two inputs:
<ul>
<li>The grammar specification.
<li>A parser template file.
</ul>
Typically, only the grammar specification is supplied by the programmer.
Lemon comes with a default parser template which works fine for most
applications. But the user is free to substitute a different parser
template if desired.</p>
<p>Depending on command-line options, Lemon will generate between
one and three files of outputs.
<ul>
<li>C code to implement the parser.
<li>A header file defining an integer ID for each terminal symbol.
<li>An information file that describes the states of the generated parser
automaton.
</ul>
By default, all three of these output files are generated.
The header file is suppressed if the ``-m'' command-line option is
used and the report file is omitted when ``-q'' is selected.</p>
<p>The grammar specification file uses a ``.y'' suffix, by convention.
In the examples used in this document, we'll assume the name of the
grammar file is ``gram.y''. A typical use of Lemon would be the
following command:
<pre>
lemon gram.y
</pre>
This command will generate three output files named ``gram.c'',
``gram.h'' and ``gram.out''.
The first is C code to implement the parser. The second
is the header file that defines numerical values for all
terminal symbols, and the last is the report that explains
the states used by the parser automaton.</p>
<h3>Command Line Options</h3>
<p>The behavior of Lemon can be modified using command-line options.
You can obtain a list of the available command-line options together
with a brief explanation of what each does by typing
<pre>
lemon -?
</pre>
As of this writing, the following command-line options are supported:
<ul>
<li><tt>-b</tt>
<li><tt>-c</tt>
<li><tt>-g</tt>
<li><tt>-m</tt>
<li><tt>-q</tt>
<li><tt>-s</tt>
<li><tt>-x</tt>
</ul>
The ``-b'' option reduces the amount of text in the report file by
printing only the basis of each parser state, rather than the full
configuration.
The ``-c'' option suppresses action table compression. Using -c
will make the parser a little larger and slower but it will detect
syntax errors sooner.
The ``-g'' option causes no output files to be generated at all.
Instead, the input grammar file is printed on standard output but
with all comments, actions and other extraneous text deleted. This
is a useful way to get a quick summary of a grammar.
The ``-m'' option causes the output C source file to be compatible
with the ``makeheaders'' program.
Makeheaders is a program that automatically generates header files
from C source code. When the ``-m'' option is used, the header
file is not output since the makeheaders program will take care
of generated all header files automatically.
The ``-q'' option suppresses the report file.
Using ``-s'' causes a brief summary of parser statistics to be
printed. Like this:
<pre>
Parser statistics: 74 terminals, 70 nonterminals, 179 rules
340 states, 2026 parser table entries, 0 conflicts
</pre>
Finally, the ``-x'' option causes Lemon to print its version number
and then stops without attempting to read the grammar or generate a parser.</p>
<h3>The Parser Interface</h3>
<p>Lemon doesn't generate a complete, working program. It only generates
a few subroutines that implement a parser. This section describes
the interface to those subroutines. It is up to the programmer to
call these subroutines in an appropriate way in order to produce a
complete system.</p>
<p>Before a program begins using a Lemon-generated parser, the program
must first create the parser.
A new parser is created as follows:
<pre>
void *pParser = ParseAlloc( malloc );
</pre>
The ParseAlloc() routine allocates and initializes a new parser and
returns a pointer to it.
The actual data structure used to represent a parser is opaque --
its internal structure is not visible or usable by the calling routine.
For this reason, the ParseAlloc() routine returns a pointer to void
rather than a pointer to some particular structure.
The sole argument to the ParseAlloc() routine is a pointer to the
subroutine used to allocate memory. Typically this means ``malloc()''.</p>
<p>After a program is finished using a parser, it can reclaim all
memory allocated by that parser by calling
<pre>
ParseFree(pParser, free);
</pre>
The first argument is the same pointer returned by ParseAlloc(). The
second argument is a pointer to the function used to release bulk
memory back to the system.</p>
<p>After a parser has been allocated using ParseAlloc(), the programmer
must supply the parser with a sequence of tokens (terminal symbols) to
be parsed. This is accomplished by calling the following function
once for each token:
<pre>
Parse(pParser, hTokenID, sTokenData, pArg);
</pre>
The first argument to the Parse() routine is the pointer returned by
ParseAlloc().
The second argument is a small positive integer that tells the parse the
type of the next token in the data stream.
There is one token type for each terminal symbol in the grammar.
The gram.h file generated by Lemon contains #define statements that
map symbolic terminal symbol names into appropriate integer values.
(A value of 0 for the second argument is a special flag to the
parser to indicate that the end of input has been reached.)
The third argument is the value of the given token. By default,
the type of the third argument is integer, but the grammar will
usually redefine this type to be some kind of structure.
Typically the second argument will be a broad category of tokens
such as ``identifier'' or ``number'' and the third argument will
be the name of the identifier or the value of the number.</p>
<p>The Parse() function may have either three or four arguments,
depending on the grammar. If the grammar specification file request
it, the Parse() function will have a fourth parameter that can be
of any type chosen by the programmer. The parser doesn't do anything
with this argument except to pass it through to action routines.
This is a convenient mechanism for passing state information down
to the action routines without having to use global variables.</p>
<p>A typical use of a Lemon parser might look something like the
following:
<pre>
01 ParseTree *ParseFile(const char *zFilename){
02 Tokenizer *pTokenizer;
03 void *pParser;
04 Token sToken;
05 int hTokenId;
06 ParserState sState;
07
08 pTokenizer = TokenizerCreate(zFilename);
09 pParser = ParseAlloc( malloc );
10 InitParserState(&sState);
11 while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
12 Parse(pParser, hTokenId, sToken, &sState);
13 }
14 Parse(pParser, 0, sToken, &sState);
15 ParseFree(pParser, free );
16 TokenizerFree(pTokenizer);
17 return sState.treeRoot;
18 }
</pre>
This example shows a user-written routine that parses a file of
text and returns a pointer to the parse tree.
(We've omitted all error-handling from this example to keep it
simple.)
We assume the existence of some kind of tokenizer which is created
using TokenizerCreate() on line 8 and deleted by TokenizerFree()
on line 16. The GetNextToken() function on line 11 retrieves the
next token from the input file and puts its type in the
integer variable hTokenId. The sToken variable is assumed to be
some kind of structure that contains details about each token,
such as its complete text, what line it occurs on, etc. </p>
<p>This example also assumes the existence of structure of type
ParserState that holds state information about a particular parse.
An instance of such a structure is created on line 6 and initialized
on line 10. A pointer to this structure is passed into the Parse()
routine as the optional 4th argument.
The action routine specified by the grammar for the parser can use
the ParserState structure to hold whatever information is useful and
appropriate. In the example, we note that the treeRoot field of
the ParserState structure is left pointing to the root of the parse
tree.</p>
<p>The core of this example as it relates to Lemon is as follows:
<pre>
ParseFile(){
pParser = ParseAlloc( malloc );
while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){
Parse(pParser, hTokenId, sToken);
}
Parse(pParser, 0, sToken);
ParseFree(pParser, free );
}
</pre>
Basically, what a program has to do to use a Lemon-generated parser
is first create the parser, then send it lots of tokens obtained by
tokenizing an input source. When the end of input is reached, the
Parse() routine should be called one last time with a token type
of 0. This step is necessary to inform the parser that the end of
input has been reached. Finally, we reclaim memory used by the
parser by calling ParseFree().</p>
<p>There is one other interface routine that should be mentioned
before we move on.
The ParseTrace() function can be used to generate debugging output
from the parser. A prototype for this routine is as follows:
<pre>
ParseTrace(FILE *stream, char *zPrefix);
</pre>
After this routine is called, a short (one-line) message is written
to the designated output stream every time the parser changes states
or calls an action routine. Each such message is prefaced using
the text given by zPrefix. This debugging output can be turned off
by calling ParseTrace() again with a first argument of NULL (0).</p>
<h3>Differences With YACC and BISON</h3>
<p>Programmers who have previously used the yacc or bison parser
generator will notice several important differences between yacc and/or
bison and Lemon.
<ul>
<li>In yacc and bison, the parser calls the tokenizer. In Lemon,
the tokenizer calls the parser.
<li>Lemon uses no global variables. Yacc and bison use global variables
to pass information between the tokenizer and parser.
<li>Lemon allows multiple parsers to be running simultaneously. Yacc
and bison do not.
</ul>
These differences may cause some initial confusion for programmers
with prior yacc and bison experience.
But after years of experience using Lemon, I firmly
believe that the Lemon way of doing things is better.</p>
<h2>Input File Syntax</h2>
<p>The main purpose of the grammar specification file for Lemon is
to define the grammar for the parser. But the input file also
specifies additional information Lemon requires to do its job.
Most of the work in using Lemon is in writing an appropriate
grammar file.</p>
<p>The grammar file for lemon is, for the most part, free format.
It does not have sections or divisions like yacc or bison. Any
declaration can occur at any point in the file.
Lemon ignores whitespace (except where it is needed to separate
tokens) and it honors the same commenting conventions as C and C++.</p>
<h3>Terminals and Nonterminals</h3>
<p>A terminal symbol (token) is any string of alphanumeric
and underscore characters
that begins with an upper case letter.
A terminal can contain lower class letters after the first character,
but the usual convention is to make terminals all upper case.
A nonterminal, on the other hand, is any string of alphanumeric
and underscore characters than begins with a lower case letter.
Again, the usual convention is to make nonterminals use all lower
case letters.</p>
<p>In Lemon, terminal and nonterminal symbols do not need to
be declared or identified in a separate section of the grammar file.
Lemon is able to generate a list of all terminals and nonterminals
by examining the grammar rules, and it can always distinguish a
terminal from a nonterminal by checking the case of the first
character of the name.</p>
<p>Yacc and bison allow terminal symbols to have either alphanumeric
names or to be individual characters included in single quotes, like
this: ')' or '$'. Lemon does not allow this alternative form for
terminal symbols. With Lemon, all symbols, terminals and nonterminals,
must have alphanumeric names.</p>
<h3>Grammar Rules</h3>
<p>The main component of a Lemon grammar file is a sequence of grammar
rules.
Each grammar rule consists of a nonterminal symbol followed by
the special symbol ``::='' and then a list of terminals and/or nonterminals.
The rule is terminated by a period.
The list of terminals and nonterminals on the right-hand side of the
rule can be empty.
Rules can occur in any order, except that the left-hand side of the
first rule is assumed to be the start symbol for the grammar (unless
specified otherwise using the <tt>%start</tt> directive described below.)
A typical sequence of grammar rules might look something like this:
<pre>
expr ::= expr PLUS expr.
expr ::= expr TIMES expr.
expr ::= LPAREN expr RPAREN.
expr ::= VALUE.
</pre>
</p>
<p>There is one non-terminal in this example, ``expr'', and five
terminal symbols or tokens: ``PLUS'', ``TIMES'', ``LPAREN'',
``RPAREN'' and ``VALUE''.</p>
<p>Like yacc and bison, Lemon allows the grammar to specify a block
of C code that will be executed whenever a grammar rule is reduced
by the parser.
In Lemon, this action is specified by putting the C code (contained
within curly braces <tt>{...}</tt>) immediately after the
period that closes the rule.
For example:
<pre>
expr ::= expr PLUS expr. { printf("Doing an addition...\n"); }
</pre>
</p>
<p>In order to be useful, grammar actions must normally be linked to
their associated grammar rules.
In yacc and bison, this is accomplished by embedding a ``$$'' in the
action to stand for the value of the left-hand side of the rule and
symbols ``$1'', ``$2'', and so forth to stand for the value of
the terminal or nonterminal at position 1, 2 and so forth on the
right-hand side of the rule.
This idea is very powerful, but it is also very error-prone. The
single most common source of errors in a yacc or bison grammar is
to miscount the number of symbols on the right-hand side of a grammar
rule and say ``$7'' when you really mean ``$8''.</p>
<p>Lemon avoids the need to count grammar symbols by assigning symbolic
names to each symbol in a grammar rule and then using those symbolic
names in the action.
In yacc or bison, one would write this:
<pre>
expr -> expr PLUS expr { $$ = $1 + $3; };
</pre>
But in Lemon, the same rule becomes the following:
<pre>
expr(A) ::= expr(B) PLUS expr(C). { A = B+C; }
</pre>
In the Lemon rule, any symbol in parentheses after a grammar rule
symbol becomes a place holder for that symbol in the grammar rule.
This place holder can then be used in the associated C action to
stand for the value of that symbol.<p>
<p>The Lemon notation for linking a grammar rule with its reduce
action is superior to yacc/bison on several counts.
First, as mentioned above, the Lemon method avoids the need to
count grammar symbols.
Secondly, if a terminal or nonterminal in a Lemon grammar rule
includes a linking symbol in parentheses but that linking symbol
is not actually used in the reduce action, then an error message
is generated.
For example, the rule
<pre>
expr(A) ::= expr(B) PLUS expr(C). { A = B; }
</pre>
will generate an error because the linking symbol ``C'' is used
in the grammar rule but not in the reduce action.</p>
<p>The Lemon notation for linking grammar rules to reduce actions
also facilitates the use of destructors for reclaiming memory
allocated by the values of terminals and nonterminals on the
right-hand side of a rule.</p>
<h3>Precedence Rules</h3>
<p>Lemon resolves parsing ambiguities in exactly the same way as
yacc and bison. A shift-reduce conflict is resolved in favor
of the shift, and a reduce-reduce conflict is resolved by reducing
whichever rule comes first in the grammar file.</p>
<p>Just like in
yacc and bison, Lemon allows a measure of control
over the resolution of paring conflicts using precedence rules.
A precedence value can be assigned to any terminal symbol
using the %left, %right or %nonassoc directives. Terminal symbols
mentioned in earlier directives have a lower precedence that
terminal symbols mentioned in later directives. For example:</p>
<p><pre>
%left AND.
%left OR.
%nonassoc EQ NE GT GE LT LE.
%left PLUS MINUS.
%left TIMES DIVIDE MOD.
%right EXP NOT.
</pre></p>
<p>In the preceding sequence of directives, the AND operator is
defined to have the lowest precedence. The OR operator is one
precedence level higher. And so forth. Hence, the grammar would
attempt to group the ambiguous expression
<pre>
a AND b OR c
</pre>
like this
<pre>
a AND (b OR c).
</pre>
The associativity (left, right or nonassoc) is used to determine
the grouping when the precedence is the same. AND is left-associative
in our example, so
<pre>
a AND b AND c
</pre>
is parsed like this
<pre>
(a AND b) AND c.
</pre>
The EXP operator is right-associative, though, so
<pre>
a EXP b EXP c
</pre>
is parsed like this
<pre>
a EXP (b EXP c).
</pre>
The nonassoc precedence is used for non-associative operators.
So
<pre>
a EQ b EQ c
</pre>
is an error.</p>
<p>The precedence of non-terminals is transferred to rules as follows:
The precedence of a grammar rule is equal to the precedence of the
left-most terminal symbol in the rule for which a precedence is
defined. This is normally what you want, but in those cases where
you want to precedence of a grammar rule to be something different,
you can specify an alternative precedence symbol by putting the
symbol in square braces after the period at the end of the rule and
before any C-code. For example:</p>
<p><pre>
expr = MINUS expr. [NOT]
</pre></p>
<p>This rule has a precedence equal to that of the NOT symbol, not the
MINUS symbol as would have been the case by default.</p>
<p>With the knowledge of how precedence is assigned to terminal
symbols and individual
grammar rules, we can now explain precisely how parsing conflicts
are resolved in Lemon. Shift-reduce conflicts are resolved
as follows:
<ul>
<li> If either the token to be shifted or the rule to be reduced
lacks precedence information, then resolve in favor of the
shift, but report a parsing conflict.
<li> If the precedence of the token to be shifted is greater than
the precedence of the rule to reduce, then resolve in favor
of the shift. No parsing conflict is reported.
<li> If the precedence of the token it be shifted is less than the
precedence of the rule to reduce, then resolve in favor of the
reduce action. No parsing conflict is reported.
<li> If the precedences are the same and the shift token is
right-associative, then resolve in favor of the shift.
No parsing conflict is reported.
<li> If the precedences are the same the the shift token is
left-associative, then resolve in favor of the reduce.
No parsing conflict is reported.
<li> Otherwise, resolve the conflict by doing the shift and
report the parsing conflict.
</ul>
Reduce-reduce conflicts are resolved this way:
<ul>
<li> If either reduce rule
lacks precedence information, then resolve in favor of the
rule that appears first in the grammar and report a parsing
conflict.
<li> If both rules have precedence and the precedence is different
then resolve the dispute in favor of the rule with the highest
precedence and do not report a conflict.
<li> Otherwise, resolve the conflict by reducing by the rule that
appears first in the grammar and report a parsing conflict.
</ul>
<h3>Special Directives</h3>
<p>The input grammar to Lemon consists of grammar rules and special
directives. We've described all the grammar rules, so now we'll
talk about the special directives.</p>
<p>Directives in lemon can occur in any order. You can put them before
the grammar rules, or after the grammar rules, or in the mist of the
grammar rules. It doesn't matter. The relative order of
directives used to assign precedence to terminals is important, but
other than that, the order of directives in Lemon is arbitrary.</p>
<p>Lemon supports the following special directives:
<ul>
<li><tt>%code</tt>
<li><tt>%default_destructor</tt>
<li><tt>%default_type</tt>
<li><tt>%destructor</tt>
<li><tt>%extra_argument</tt>
<li><tt>%include</tt>
<li><tt>%left</tt>
<li><tt>%name</tt>
<li><tt>%nonassoc</tt>
<li><tt>%parse_accept</tt>
<li><tt>%parse_failure </tt>
<li><tt>%right</tt>
<li><tt>%stack_overflow</tt>
<li><tt>%stack_size</tt>
<li><tt>%start_symbol</tt>
<li><tt>%syntax_error</tt>
<li><tt>%token_destructor</tt>
<li><tt>%token_prefix</tt>
<li><tt>%token_type</tt>
<li><tt>%type</tt>
</ul>
Each of these directives will be described separately in the
following sections:</p>
<h4>The <tt>%code</tt> directive</h4>
<p>The %code directive is used to specify addition C/C++ code that
is added to the end of the main output file. This is similar to
the %include directive except that %include is inserted at the
beginning of the main output file.</p>
<p>%code is typically used to include some action routines or perhaps
a tokenizer as part of the output file.</p>
<h4>The <tt>%default_destructor</tt> directive</h4>
<p>The %default_destructor directive specifies a destructor to
use for non-terminals that do not have their own destructor
specified by a separate %destructor directive. See the documentation
on the %destructor directive below for additional information.</p>
<p>In some grammers, many different non-terminal symbols have the
same datatype and hence the same destructor. This directive is
a convenience way to specify the same destructor for all those
non-terminals using a single statement.</p>
<h4>The <tt>%default_type</tt> directive</h4>
<p>The %default_type directive specifies the datatype of non-terminal
symbols that do no have their own datatype defined using a separate
%type directive. See the documentation on %type below for addition
information.</p>
<h4>The <tt>%destructor</tt> directive</h4>
<p>The %destructor directive is used to specify a destructor for
a non-terminal symbol.
(See also the %token_destructor directive which is used to
specify a destructor for terminal symbols.)</p>
<p>A non-terminal's destructor is called to dispose of the
non-terminal's value whenever the non-terminal is popped from
the stack. This includes all of the following circumstances:
<ul>
<li> When a rule reduces and the value of a non-terminal on
the right-hand side is not linked to C code.
<li> When the stack is popped during error processing.
<li> When the ParseFree() function runs.
</ul>
The destructor can do whatever it wants with the value of
the non-terminal, but its design is to deallocate memory
or other resources held by that non-terminal.</p>
<p>Consider an example:
<pre>
%type nt {void*}
%destructor nt { free($$); }
nt(A) ::= ID NUM. { A = malloc( 100 ); }
</pre>
This example is a bit contrived but it serves to illustrate how
destructors work. The example shows a non-terminal named
``nt'' that holds values of type ``void*''. When the rule for
an ``nt'' reduces, it sets the value of the non-terminal to
space obtained from malloc(). Later, when the nt non-terminal
is popped from the stack, the destructor will fire and call
free() on this malloced space, thus avoiding a memory leak.
(Note that the symbol ``$$'' in the destructor code is replaced
by the value of the non-terminal.)</p>
<p>It is important to note that the value of a non-terminal is passed
to the destructor whenever the non-terminal is removed from the
stack, unless the non-terminal is used in a C-code action. If
the non-terminal is used by C-code, then it is assumed that the
C-code will take care of destroying it if it should really
be destroyed. More commonly, the value is used to build some
larger structure and we don't want to destroy it, which is why
the destructor is not called in this circumstance.</p>
<p>By appropriate use of destructors, it is possible to
build a parser using Lemon that can be used within a long-running
program, such as a GUI, that will not leak memory or other resources.
To do the same using yacc or bison is much more difficult.</p>
<h4>The <tt>%extra_argument</tt> directive</h4>
The %extra_argument directive instructs Lemon to add a 4th parameter
to the parameter list of the Parse() function it generates. Lemon
doesn't do anything itself with this extra argument, but it does
make the argument available to C-code action routines, destructors,
and so forth. For example, if the grammar file contains:</p>
<p><pre>
%extra_argument { MyStruct *pAbc }
</pre></p>
<p>Then the Parse() function generated will have an 4th parameter
of type ``MyStruct*'' and all action routines will have access to
a variable named ``pAbc'' that is the value of the 4th parameter
in the most recent call to Parse().</p>
<h4>The <tt>%include</tt> directive</h4>
<p>The %include directive specifies C code that is included at the
top of the generated parser. You can include any text you want --
the Lemon parser generator copies it blindly. If you have multiple
%include directives in your grammar file the value of the last
%include directive overwrites all the others.</p.
<p>The %include directive is very handy for getting some extra #include
preprocessor statements at the beginning of the generated parser.
For example:</p>
<p><pre>
%include {#include &lt;unistd.h&gt;}
</pre></p>
<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyed in unistd.h.</p>
<h4>The <tt>%left</tt> directive</h4>
The %left directive is used (along with the %right and
%nonassoc directives) to declare precedences of terminal
symbols. Every terminal symbol whose name appears after
a %left directive but before the next period (``.'') is
given the same left-associative precedence value. Subsequent
%left directives have higher precedence. For example:</p>
<p><pre>
%left AND.
%left OR.
%nonassoc EQ NE GT GE LT LE.
%left PLUS MINUS.
%left TIMES DIVIDE MOD.
%right EXP NOT.
</pre></p>
<p>Note the period that terminates each %left, %right or %nonassoc
directive.</p>
<p>LALR(1) grammars can get into a situation where they require
a large amount of stack space if you make heavy use or right-associative
operators. For this reason, it is recommended that you use %left
rather than %right whenever possible.</p>
<h4>The <tt>%name</tt> directive</h4>
<p>By default, the functions generated by Lemon all begin with the
five-character string ``Parse''. You can change this string to something
different using the %name directive. For instance:</p>
<p><pre>
%name Abcde
</pre></p>
<p>Putting this directive in the grammar file will cause Lemon to generate
functions named
<ul>
<li> AbcdeAlloc(),
<li> AbcdeFree(),
<li> AbcdeTrace(), and
<li> Abcde().
</ul>
The %name directive allows you to generator two or more different
parsers and link them all into the same executable.
</p>
<h4>The <tt>%nonassoc</tt> directive</h4>
<p>This directive is used to assign non-associative precedence to
one or more terminal symbols. See the section on precedence rules
or on the %left directive for additional information.</p>
<h4>The <tt>%parse_accept</tt> directive</h4>
<p>The %parse_accept directive specifies a block of C code that is
executed whenever the parser accepts its input string. To ``accept''
an input string means that the parser was able to process all tokens
without error.</p>
<p>For example:</p>
<p><pre>
%parse_accept {
printf("parsing complete!\n");
}
</pre></p>
<h4>The <tt>%parse_failure</tt> directive</h4>
<p>The %parse_failure directive specifies a block of C code that
is executed whenever the parser fails complete. This code is not
executed until the parser has tried and failed to resolve an input
error using is usual error recovery strategy. The routine is
only invoked when parsing is unable to continue.</p>
<p><pre>
%parse_failure {
fprintf(stderr,"Giving up. Parser is hopelessly lost...\n");
}
</pre></p>
<h4>The <tt>%right</tt> directive</h4>
<p>This directive is used to assign right-associative precedence to
one or more terminal symbols. See the section on precedence rules
or on the %left directive for additional information.</p>
<h4>The <tt>%stack_overflow</tt> directive</h4>
<p>The %stack_overflow directive specifies a block of C code that
is executed if the parser's internal stack ever overflows. Typically
this just prints an error message. After a stack overflow, the parser
will be unable to continue and must be reset.</p>
<p><pre>
%stack_overflow {
fprintf(stderr,"Giving up. Parser stack overflow\n");
}
</pre></p>
<p>You can help prevent parser stack overflows by avoiding the use
of right recursion and right-precedence operators in your grammar.
Use left recursion and and left-precedence operators instead, to
encourage rules to reduce sooner and keep the stack size down.
For example, do rules like this:
<pre>
list ::= list element. // left-recursion. Good!
list ::= .
</pre>
Not like this:
<pre>
list ::= element list. // right-recursion. Bad!
list ::= .
</pre>
<h4>The <tt>%stack_size</tt> directive</h4>
<p>If stack overflow is a problem and you can't resolve the trouble
by using left-recursion, then you might want to increase the size
of the parser's stack using this directive. Put an positive integer
after the %stack_size directive and Lemon will generate a parse
with a stack of the requested size. The default value is 100.</p>
<p><pre>
%stack_size 2000
</pre></p>
<h4>The <tt>%start_symbol</tt> directive</h4>
<p>By default, the start-symbol for the grammar that Lemon generates
is the first non-terminal that appears in the grammar file. But you
can choose a different start-symbol using the %start_symbol directive.</p>
<p><pre>
%start_symbol prog
</pre></p>
<h4>The <tt>%token_destructor</tt> directive</h4>
<p>The %destructor directive assigns a destructor to a non-terminal
symbol. (See the description of the %destructor directive above.)
This directive does the same thing for all terminal symbols.</p>
<p>Unlike non-terminal symbols which may each have a different data type
for their values, terminals all use the same data type (defined by
the %token_type directive) and so they use a common destructor. Other
than that, the token destructor works just like the non-terminal
destructors.</p>
<h4>The <tt>%token_prefix</tt> directive</h4>
<p>Lemon generates #defines that assign small integer constants
to each terminal symbol in the grammar. If desired, Lemon will
add a prefix specified by this directive
to each of the #defines it generates.
So if the default output of Lemon looked like this:
<pre>
#define AND 1
#define MINUS 2
#define OR 3
#define PLUS 4
</pre>
You can insert a statement into the grammar like this:
<pre>
%token_prefix TOKEN_
</pre>
to cause Lemon to produce these symbols instead:
<pre>
#define TOKEN_AND 1
#define TOKEN_MINUS 2
#define TOKEN_OR 3
#define TOKEN_PLUS 4
</pre>
<h4>The <tt>%token_type</tt> and <tt>%type</tt> directives</h4>
<p>These directives are used to specify the data types for values
on the parser's stack associated with terminal and non-terminal
symbols. The values of all terminal symbols must be of the same
type. This turns out to be the same data type as the 3rd parameter
to the Parse() function generated by Lemon. Typically, you will
make the value of a terminal symbol by a pointer to some kind of
token structure. Like this:</p>
<p><pre>
%token_type {Token*}
</pre></p>
<p>If the data type of terminals is not specified, the default value
is ``int''.</p>
<p>Non-terminal symbols can each have their own data types. Typically
the data type of a non-terminal is a pointer to the root of a parse-tree
structure that contains all information about that non-terminal.
For example:</p>
<p><pre>
%type expr {Expr*}
</pre></p>
<p>Each entry on the parser's stack is actually a union containing
instances of all data types for every non-terminal and terminal symbol.
Lemon will automatically use the correct element of this union depending
on what the corresponding non-terminal or terminal symbol is. But
the grammar designer should keep in mind that the size of the union
will be the size of its largest element. So if you have a single
non-terminal whose data type requires 1K of storage, then your 100
entry parser stack will require 100K of heap space. If you are willing
and able to pay that price, fine. You just need to know.</p>
<h3>Error Processing</h3>
<p>After extensive experimentation over several years, it has been
discovered that the error recovery strategy used by yacc is about
as good as it gets. And so that is what Lemon uses.</p>
<p>When a Lemon-generated parser encounters a syntax error, it
first invokes the code specified by the %syntax_error directive, if
any. It then enters its error recovery strategy. The error recovery
strategy is to begin popping the parsers stack until it enters a
state where it is permitted to shift a special non-terminal symbol
named ``error''. It then shifts this non-terminal and continues
parsing. But the %syntax_error routine will not be called again
until at least three new tokens have been successfully shifted.</p>
<p>If the parser pops its stack until the stack is empty, and it still
is unable to shift the error symbol, then the %parse_failed routine
is invoked and the parser resets itself to its start state, ready
to begin parsing a new file. This is what will happen at the very
first syntax error, of course, if there are no instances of the
``error'' non-terminal in your grammar.</p>
</body>
</html>

View file

View file

@ -1,206 +0,0 @@
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1685518550,
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1660459072,
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1693660503,
"narHash": "sha256-B/g2V4v6gjirFmy+I5mwB2bCYc0l3j5scVfwgl6WOl8=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "bd5bdbb52350e145c526108f4ef192eb8e554fa0",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1697722682,
"narHash": "sha256-PRhNRNxBEsf4hdpuGIGcRckyYGm5iGuI9P0UGzOmzEo=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "8e8f3e83b66a6a9a9e953e4a14b1a227b22a18d4",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1685801374,
"narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c37ca420157f4abc31e26f436c1145f8951ff373",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1689261696,
"narHash": "sha256-LzfUtFs9MQRvIoQ3MfgSuipBVMXslMPH/vZ+nM40LkA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "df1eee2aa65052a18121ed4971081576b25d6b5c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils_2",
"gitignore": "gitignore",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1696846637,
"narHash": "sha256-0hv4kbXxci2+pxhuXlVgftj/Jq79VSmtAyvfabCCtYk=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "42e1b6095ef80a51f79595d9951eb38e91c4e6ca",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

104
flake.nix
View file

@ -1,104 +0,0 @@
{
description = "The DBSQL library, a mixup of SQLite and Berkeley DB";
nixConfig = {
bash-prompt = "\\[\\e[34;1m\\]nix ~ \\[\\e[0m\\]";
};
inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
inputs.pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
inputs.nix-github-actions.url = "github:nix-community/nix-github-actions";
inputs.nix-github-actions.inputs.nixpkgs.follows = "nixpkgs";
outputs = { self, nixpkgs, flake-utils, pre-commit-hooks, nix-github-actions }:
let
inherit (nixpkgs) lib;
officialRelease = false;
#version = "DBSQL ${DBSQL_VERSION}: (${versionSuffix})";
version = "DBSQL 0.3.1: (${versionSuffix})";
versionSuffix =
if officialRelease
then ""
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}_${self.shortRev or "dirty"}";
supportedSystems = [ "x86_64-linux" ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = forAllSystems (system: import nixpkgs {
inherit system;
overlays = [ self.overlay ];
});
in
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [
(final: prev: {
dbsql = with final; stdenv.mkDerivation rec {
inherit version;
inherit system;
pname = "dbsql";
src = self;
configureFlags = [
"--host ${system}"
];
buildInputs = [
(enableDebuging db4)
glibc.out
glibc.static
tcl-8_5
];
nativeBuildInputs = [ autoreconfHook ];
meta = {
changelog = "https://git.burd.me/greg/dbsql/raw/branch/main/ChangeLog";
downloadPage = "https://git.burd.me/greg/dbsql/releases";
homepage = "https://github.com/gburd/dbsql";
license = "https://github.com/gburd/dbsql/LICENSE";
mainProgram = "dbsql";
maintainers = [ "Greg Burd <greg@burd.me>" ];
platforms = supportedSystems;
};
};
})
];
checks = {
pre-commit-check = pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
nixpkgs-fmt.enable = true;
};
};
};
devShell = nixpkgs.legacyPackages.${system}.mkShell {
inherit (self.checks.${system}.pre-commit-check) shellHook;
};
};
in rec {
packages = {
inherit (pkgs) dbsql;
githubActions = nix-github-actions.lib.mkGithubMatrix {
checks = nixpkgs.lib.getAttrs [ "x86_64-linux" "x86_64-darwin" ] self.packages;
};
};
packages.default = self.packages.${system}.dbsql;
packages.container = pkgs.callPackage ./container.nix { package = packages.default; };
apps.dbsql = flake-utils.lib.mkApp { drv = packages.default; };
apps.${system}.default = apps.dbsql;
devShells.default = import ./shell.nix { inherit pkgs; };
}
);
}

43
index.html Normal file
View file

@ -0,0 +1,43 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>DBSQL by gburd</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<h1>DBSQL</h1>
<p>A SQL database engine on top of Oracle Berkeley DB</p>
<p class="view"><a href="https://github.com/gburd/dbsql">View the Project on GitHub <small>gburd/dbsql</small></a></p>
<ul>
<li><a href="https://github.com/gburd/dbsql/zipball/master">Download <strong>ZIP File</strong></a></li>
<li><a href="https://github.com/gburd/dbsql/tarball/master">Download <strong>TAR Ball</strong></a></li>
<li><a href="https://github.com/gburd/dbsql">View On <strong>GitHub</strong></a></li>
</ul>
</header>
<section>
<h3>DB SQL</h3>
<p>This project isn't under active development. Years ago I set about to reuse the <a href="http://sqlite.org/">SQLite</a> source with Berkeley DB functioning as the storage manager. As I set about to do this I also completely changed the SQLite code, mostly in format but with some other changes. The project finished up when DBSQL was functional, but not fully debugged. I used this prototype to help justify the work to do much the same within the Berkeley DB group in Oracle. Berkeley DB now has a good integration with SQLite, so this project is defunct.</p>
</section>
<footer>
<p>This project is maintained by <a href="https://github.com/gburd">gburd</a></p>
<p><small>Hosted on GitHub Pages &mdash; Theme by <a href="https://github.com/orderedlist">orderedlist</a></small></p>
</footer>
</div>
<script src="javascripts/scale.fix.js"></script>
</body>
</html>

17
javascripts/scale.fix.js Normal file
View file

@ -0,0 +1,17 @@
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}

1
params.json Normal file
View file

@ -0,0 +1 @@
{"note":"Don't delete this file! It's used internally to help with page regeneration.","tagline":"A SQL database engine on top of Oracle Berkeley DB","body":"### DB SQL\r\nThis project isn't under active development. Years ago I set about to reuse the [SQLite](http://sqlite.org/) source with Berkeley DB functioning as the storage manager. As I set about to do this I also completely changed the SQLite code, mostly in format but with some other changes. The project finished up when DBSQL was functional, but not fully debugged. I used this prototype to help justify the work to do much the same within the Berkeley DB group in Oracle. Berkeley DB now has a good integration with SQLite, so this project is defunct.","name":"DBSQL","google":""}

View file

@ -1,28 +0,0 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs.buildPackages; [
act
autoconf
ed
gcc
gdb
gettext
libtool
m4
pkg-config
perl
ripgrep
python3
];
buildInputs = with pkgs; [
# (enableDebuging db4)
db4
glibc.out
glibc.static
tcl-8_5
];
DOCKER_BUILDKIT = 1;
}

141
src/TODO
View file

@ -1,141 +0,0 @@
--- Things to fix before 1.0
* search for TODO and fix in all files
* review use of __os_malloc verses __os_umalloc
* strcasecmp.c: what about UNICODE?
* --enable-sqlite-compat create the sqlite compat api
* --disable-statistics
* command line tools
* dbsql
* --bcp bulk copy from file
* integrate the new 4.3 unique id generation
* replace NDEBUG with DIAGNOSTIC
* ask about optimizations for MySQL, incorporate into DBSQL
* modify types to be less ambiguous int -> u_int32_t
* work bottom up, and top down knitting DB access patterns in
* grep for 'return [0-9]+' and replace with #defines that make more sense
* change all 'return XXX;' statements to be 'return (XXX);'
* replace '(char*)0' with NULL or some such thing
* look for and try to replace (void*) casts
* move dbsql_get_encoding global into DBSQL->[get,set]_encoding()
* rewrite error reporting, get rid of __str_urealloc and err_msgs
* lint, lclint and splint checking
* spell check comments, docs, etc - add standard spell.ok etc stuff
* grep for "Malloc Failed", fix
* replace home grown linked lists(src_list) with macro implementations of same
* dbsql_create_env() should do the following as a default setup:
To minimize the amount of space taken up by the log files,
configure Berkeley DB to have small log files (see the
DbEnv.set_lg_max method), do frequent checkpoints (see the
DbEnv.txn_checkpoint method), and automatically remove log
files (see the DB_LOG_AUTOREMOVE flag to the DbEnv.set_flags
method). -- Keith
* purify - memory leak/buffer overrun check
* profile - gprof(1) - profile run, look for hot spots
* produce and examine a code coverage report
* fix places where I moved local scope vars to function scope vars (as I go)
* consider using a DB_SEQ for 'int priorNewRowid; /* Last generated ROWID */'
* what is the difference between DBSQL_STATUS_ERROR verses DBSQL_RUN_RECOVERY
when should one be used over the other? check usage.
* DBSQL->{sg}et_verbose
* stats?
* How will TRIGGERS work in a multi env setup or worse yet, when replicated?
* add .describe [command] ('.describe select') to dbsql
* add .edit [!n] to open $EDITOR on historical statement
* examine the MySQL command line interface, add best features
* TRUNCATE table [tablename]
* use something similar to readline in shell (but not readline, its GPL)
--- 1.1
* cxx
* Java
* JDBC type ???
* make the data types user definable via codec functions
* ASSOCIATE select_stmt WITH db_database_name [READ ONLY|READ WRITE]
KEY 'printf format expression' VALUE AS 'printf format expression'
* select @@IDENTITY
* SEQUENCE http://otn.oracle.com/products/rdb/pdf/0307_sequences.pdf
* XOpen CLI (==ODBC) implementation
* --enable-regex-like (e.g. 'SELECT * from Person where name like /B(u|i|y)rd/;')
--- 2.0
* note that cg_where.c has a WHERE clause limit of 100 search for wc_exprs[101]
* note in cg_where.c that if the 33rd table of a join has an index it won't
be found or used as the bitmask method uses an u_int_32, consider fixing this
* LibSDB interface http://siag.nu/libsdb/
* --enable-xml
http://www.throwingbeans.org/tech/postgresql_and_xml.html
http://weblog.infoworld.com/udell/2003/03/12.html#a637
http://www.sqlxml.org/
http://www.perfectxml.com/SQLXML.asp
http://www.sqlxml.org/faqs.aspx?faq=103
* 64bit clean http://www.treblig.org/articles/64bits.html
* Create View INFORMATION_SCHEMA_TABLES as
Select * from ( select 'main' as TABLE_CATALOG , 'sqlite' as TABLE_SCHEMA , tbl_name as TABLE_NAME , case when type = 'table' then 'BASE TABLE' when type = 'view' then 'VIEW' end as TABLE_TYPE, sql as TABLE_SOURCE from sqlite_master where type in('table','view') and tbl_name not like 'INFORMATION_SCHEMA_%' union select 'main' as TABLE_CATALOG , 'sqlite' as TABLE_SCHEMA , tbl_name as TABLE_NAME , case when type = 'table' then 'TEMPORARY TABLE' when type = 'view' then 'TEMPORARY VIEW' end as TABLE_TYPE, sql as TABLE_SOURCE from sqlite_temp_master where type in('table','view') and tbl_name not like 'INFORMATION_SCHEMA_%' ) BT order by TABLE_TYPE , TABLE_NAME
--- 3.0
* --enable-full-text-searching
CONTAINS full text index, stemming, etc.
* server
* replication
* build in severial replication methods, TCP p2p, TCP broadcast,
UDP broadcast, multicast
* discovery
* on mac, use rendevous
* on UNIX use SLRP
* use kqueues, /dev/poll, rt-signals etc - I think there is a lib that abstracts this
--- Debugging
* build dbsql_sim - randomly exercises the system hoping to uncover bugs
* build dbsql_perf - measures performance of things relase/release vs baseline
* OSDB http://osdb.sourceforge.net/
--- Missing SQL92 features
* TRUNCATE table [tablename]
* ???
--- Competition
* http://mindprod.com/jgloss/sql.html
--- Everything else...
* look at the API of http://www.xtgsystems.com/linux/simdb/doc.php
* http://www.sqlsummit.com/ODBCPORT.HTM
* http://en.wikipedia.org/wiki/ODBC
* dbExpress, is it some ODBC-like API
* http://www.thinksql.co.uk/Main/Documents/Multiversion.html
* http://www.rpbourret.com/xml/XMLDatabaseProds.htm
* http://www.rpbourret.com/xml/XMLAndDatabases.htm
--- Google AdWords
MySQL, sql, sql92, sqlite, jet database, ms access, access, sql engine,
--- References
http://www.wiscorp.com/SQLStandards.html
http://www.ocelot.ca/nist.htm
http://www.jcc.com/SQLPages/jccs_sql.htm
http://www.tdan.com/i016hy01.htm
http://www.mimer.com/news.asp?secId=176&itemId=10
http://www.itl.nist.gov/div897/ctg/sql-testing/sqlman60.htm
http://www.opengroup.org/public/tech/datam/sql.htm
http://www.dwm.uni-hildesheim.de/homes/r_maximi/SQL1998/CLICK_ME_SECOND.html
http://www.iam.unibe.ch/~scg/Archive/Software/FreeDB/FreeDB.list.html
http://www.infres.enst.fr/naw-home/doc/srfsqlhtml_bnf.html
http://www.ontko.com/~rayo/database.html
http://www.ocelot.ca/sites.htm
http://www.sqlcorner.com/
http://www.codebox.8m.com/sql.htm
http://sqlzoo.net/sql92.html
http://www.opengroup.org/testing/testsuites/nistsql.htm
http://ou800doc.caldera.com/SDK_netapi/CTOC-xtiN.intro.html
http://cui.unige.ch/db-research/Enseignement/analyseinfo/SQL7/BNFindex.html
http://cui.unige.ch/db-research/Enseignement/analyseinfo/SQL92/BNFindex.html
http://cui.unige.ch/db-research/Enseignement/analyseinfo/PLSQL21/BNFindex.html
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?relational+algebra
http://support.openlinksw.com/support/mac-faq.html
@misc{ gukal-fast,
author = "Sreenivas Gukal and Edward Omiecinski and Umakishore Ramachandran",
title = "Fast Recovery in Transient-Versioned Databases",
url = "citeseer.nj.nec.com/38354.html" }

1380
src/api.c

File diff suppressed because it is too large Load diff

View file

@ -1,270 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains the __api_get_table() and __api_free_table()
* interface routines. These are just wrappers around the main
* interface routine of DBSQL->exec().
*
* These routines are in a separate files so that they will not be linked
* if they are not used.
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <stdlib.h>
#include <string.h>
#endif
#include "dbsql_int.h"
/*
* This structure is used to pass data from __get_table() through
* to the user's callback function.
*/
typedef struct table_result {
char **result;
char *err_msgs;
u_int32_t num_result;
u_int32_t num_alloc;
u_int32_t num_row;
u_int32_t num_col;
u_int32_t num_data;
u_int32_t rc;
} table_result_t;
/*
* __get_table_cb --
* This routine is called once for each row in the result table. Its job
* is to fill in the table_result_t structure appropriately, allocating
* new memory as necessary.
*
* STATIC: static int __get_table_cb __P((void *, int, char **, char **));
*/
static int
__get_table_cb(void* arg, int ncol, char* *argv, char* *colv)
{
int rc;
table_result_t *p = (table_result_t*)arg;
int need;
int i;
char *z;
/*
* Make sure there is enough space in p->result to hold everything
* we need to remember from this invocation of the callback.
*/
if (p->num_row == 0 && argv != 0) {
need = ncol * 2;
} else {
need = ncol;
}
if (p->num_data + need >= p->num_alloc) {
p->num_alloc = (p->num_alloc * 2) + need + 1;
rc = __dbsql_realloc(NULL, sizeof(char*) * p->num_alloc,
&p->result);
if (rc == ENOMEM) {
p->rc = DBSQL_NOMEM;
return DBSQL_ERROR;
}
}
/*
* If this is the first row, then generate an extra row containing
* the names of all columns.
*/
if (p->num_row==0) {
p->num_col = ncol;
for (i = 0; i < ncol; i++) {
if (colv[i] == 0) {
z = 0;
} else {
int rc = __dbsql_malloc(NULL,
strlen(colv[i]) + 1, &z);
if (rc == ENOMEM) {
p->rc = DBSQL_NOMEM;
return DBSQL_ERROR;
}
strcpy(z, colv[i]);
}
p->result[p->num_data++] = z;
}
} else if (p->num_col != ncol) {
__str_append(&p->err_msgs,
"DBSQL->get_table() called with two or more "
"incompatible queries", (char*)0);
p->rc = DBSQL_ERROR;
return DBSQL_ERROR;
}
/*
* Copy over the row data.
*/
if (argv != 0) {
for (i = 0; i < ncol; i++) {
if (argv[i] == 0) {
z = 0;
} else {
if (__dbsql_malloc(NULL, strlen(argv[i]) + 1,
&z) == ENOMEM) {
p->rc = DBSQL_NOMEM;
return DBSQL_ERROR;
}
strcpy(z, argv[i]);
}
p->result[p->num_data++] = z;
}
p->num_row++;
}
return DBSQL_SUCCESS;
}
/*
* __api_get_table --
* Query the database. But instead of invoking a callback for each row,
* __dbsql_malloc() space to hold the result and return the entire results
* at the conclusion of the call.
* The result that is written to ***results is held in memory obtained
* from __dbsql_malloc(). But the caller cannot free this memory directly
* Instead, the entire table should be passed to DBSQL->free_table() when
* the calling procedure is finished using it.
*
* PUBLIC: int __api_get_table __P((DBSQL *, const char *, char ***, int *,
* PUBLIC: int *, char **));
*
* dbp The database on which the SQL executes
* sql The SQL to be executed
* results Write the result table here
* nrows Write the number of rows in the result here
* ncols Write the number of columns of result here
* err_msgs Write error messages here
*/
int
__api_get_table(dbp, sql, results, nrows, ncols, err_msgs)
DBSQL *dbp;
const char *sql;
char ***results;
int *nrows;
int *ncols;
char **err_msgs;
{
int rc;
table_result_t res;
DBSQL_ASSERT(results);
DBSQL_ASSERT(ncols);
DBSQL_ASSERT(nrows);
*results = 0;
*ncols = 0;
*nrows = 0;
res.err_msgs = 0;
res.num_result = 0;
res.num_row = 0;
res.num_col = 0;
res.num_data = 1;
res.num_alloc = 20;
res.rc = DBSQL_SUCCESS;
if (__dbsql_calloc(dbp, res.num_alloc, sizeof(char*),
&res.result) == ENOMEM)
return DBSQL_NOMEM;
rc = dbp->exec(dbp, sql, __get_table_cb, &res, err_msgs);
if (rc == DBSQL_ABORT) {
/* !!!
* We set this here because we're about to call free_table, but we
* have to set it again below because a realloc may have moved the
* memory around
*/
res.result[0] = res.result[1] + res.num_data;
dbp->free_table(&res.result[1]);
if (res.err_msgs) {
if(err_msgs) {
__dbsql_ufree(dbp, *err_msgs);
*err_msgs = res.err_msgs;
__str_urealloc(err_msgs);
} else {
__dbsql_free(dbp, res.err_msgs);
}
}
return res.rc;
}
__dbsql_free(dbp, res.err_msgs);
if (rc != DBSQL_SUCCESS) {
dbp->free_table(&res.result[1]);
return rc;
}
if (res.num_alloc > res.num_data) {
if(__dbsql_realloc(dbp, sizeof(char*) * (res.num_data + 1),
&res.result) == ENOMEM) {
dbp->free_table(&res.result[1]);
return DBSQL_NOMEM;
}
res.num_alloc = res.num_data + 1;
}
/* !!!
* free_table() will need to know when to stop freeing results. We use result[0]
* as a pointer to the last allocated row to be free'd. The number of rows to
* be free'd is 'result[0] - (&result[1])'.
*/
res.result[0] = res.result[1] + res.num_data;
*results = &res.result[1];
if (ncols)
*ncols = res.num_col;
if (nrows)
*nrows = res.num_row;
return rc;
}
/*
* __api_free_table --
* This routine frees the space the DBSQL->get_table() __dbsql_malloc'ed.
* There are two things to be free'd, (a) each row (results[0..n]) and then (b) the
* array 'results'. The number of rows to be free'd is 'result[-1] - (&result[0])'.
*
* PUBLIC: void __api_free_table __P((char **));
*
* result Result returned from from __api_get_table()
*/
void
__api_free_table(char* *results)
{
char *last_result;
DBSQL_ASSERT(results);
/* If this test is false then the result set is empty, only free (b) */
if (*(results - 1) != *results) {
/* !!!
* The address of the last results row is the value of the first element of
* the results array we created in get_table() but recall that we passed
* the address of the second element (&results[1]) to the user and so
* we need to read the memory of what used to be 'results[0]' which is
* now '*(results - 1)'.
*/
last_result = *(results - 1);
while (*results <= last_result) {
if (*results != NULL)
__dbsql_ufree(NULL, *results);
results++;
}
}
__dbsql_ufree(NULL, results);
}

View file

@ -1,381 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains C code routines that are called by the parser
* to handle ATTACH and DETACH statements.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __attach --
* This routine is called by the parser to process an ATTACH statement:
*
* ATTACH DATABASE filename AS dbname
*
* The 'file' and 'db' arguments are the tokens that define the
* 'file' and 'db' in the ATTACH statement.
*
* PUBLIC: void __attach __P((parser_t *, token_t *, token_t *));
*/
void
__attach(parser_t* parser, token_t* file, token_t* db)
{
int rc, i;
dbsql_db_t *new;
char *filename, *databasename;
DBSQL *dbp;
vdbe_t *v;
v = __parser_get_vdbe(parser);
__vdbe_add_op(v, OP_Halt, 0, 0);
if (parser->explain)
return;
dbp = parser->db;
if (dbp->format_version < 1) {
__error_msg(parser, "cannot attach auxiliary databases to an "
"older format master database", 0);
parser->rc = DBSQL_ERROR;
return;
}
if (dbp->nDb >= (MAX_ATTACHED + 2)) {
__error_msg(parser, "too many attached databases - max %d",
MAX_ATTACHED);
parser->rc = DBSQL_ERROR;
return;
}
filename = 0;
__str_nappend(&filename, file->z, file->n, NULL);
if (filename == 0)
return;
__str_unquote(filename);
#ifndef DBSQL_NO_AUTH
if (__auth_check(parser, DBSQL_ATTACH, filename, 0, 0) !=
DBSQL_SUCCESS) {
__dbsql_free(dbp, filename);
return;
}
#endif /* DBSQL_NO_AUTH */
databasename = 0;
__str_nappend(&databasename, db->z, db->n, NULL);
if (databasename == 0)
return;
__str_unquote(databasename);
for (i = 0; i < dbp->nDb; i++) {
if (dbp->aDb[i].zName && strcasecmp(
dbp->aDb[i].zName, databasename) == 0) {
__error_msg(parser, "database %z is already in use",
databasename);
parser->rc = DBSQL_ERROR;
__dbsql_free(dbp, filename);
return;
}
}
if (__dbsql_realloc(dbp, (sizeof(dbp->aDb[0]) *
(dbp->nDb + 1)), &dbp->aDb) == ENOMEM)
return;
new = &dbp->aDb[(dbp->nDb++)];
memset(new, 0, sizeof(*new));
if (__sqldb_init(new, dbp, filename, 0, 0, 1) != 0) {
__error_msg(parser, "unable to open database: %s", filename);
}
new->zName = databasename;
__dbsql_free(dbp, filename);
dbp->flags &= ~DBSQL_Initialized;
if (parser->nErr)
return;
if (rc == DBSQL_SUCCESS) {
rc = __init_databases(parser->db, &parser->zErrMsg);
}
if (rc) {
i = dbp->nDb - 1;
DBSQL_ASSERT(i >= 2);
if (dbp->aDb[i].pBt) {
__sm_close_db(dbp->aDb[i].pBt);
dbp->aDb[i].pBt = 0;
}
__reset_internal_schema(dbp, 0);
parser->nErr++;
parser->rc = DBSQL_ERROR;
}
}
/*
* __detach --
* This routine is called by the parser to process a DETACH statement:
*
* DETACH DATABASE db
*
* The db argument is the name of the database in the DETACH statement.
*
* PUBLIC: void __detach __P((parser_t *, token_t *));
*/
void
__detach(parser_t* parser, token_t* db)
{
int i;
DBSQL *dbp;
vdbe_t *v = __parser_get_vdbe(parser);
__vdbe_add_op(v, OP_Halt, 0, 0);
if (parser->explain)
return;
dbp = parser->db;
for (i = 0; i < dbp->nDb; i++) {
if (dbp->aDb[i].pBt == 0 ||
dbp->aDb[i].zName == 0)
continue;
if (strlen(dbp->aDb[i].zName) != db->n)
continue;
if (strncasecmp(dbp->aDb[i].zName, db->z, db->n) == 0)
break;
}
if (i >= dbp->nDb) {
__error_msg(parser, "no such database: %T", db);
return;
}
if (i < 2) {
__error_msg(parser, "cannot detach database %T", db);
return;
}
#ifndef DBSQL_NO_AUTH
if (__auth_check(parser, DBSQL_DETACH, dbp->aDb[i].zName, 0, 0) !=
DBSQL_SUCCESS) {
return;
}
#endif /* DBSQL_NO_AUTH */
__sm_close_db(dbp->aDb[i].pBt);
dbp->aDb[i].pBt = 0;
__dbsql_free(dbp, dbp->aDb[i].zName);
__reset_internal_schema(dbp, i);
dbp->nDb--;
if (i < dbp->nDb) {
dbp->aDb[i] = dbp->aDb[dbp->nDb];
memset(&dbp->aDb[dbp->nDb], 0, sizeof(dbp->aDb[0]));
__reset_internal_schema(dbp, i);
}
}
/*
* __ref_normalizer_ctx_init --
* Initialize a ref_normalizer_ctx_t structure. This routine must be
* called prior to passing the structure to one of the
* __ref_normalize_XXX() routines below. The return value indicates
* whether or not normalization is required. TRUE means we do need to
* fix the database references, FALSE means we do not.
*
* PUBLIC: int __ref_normalizer_ctx_init __P((ref_normalizer_ctx_t *,
* PUBLIC: parser_t *, int, const char *,
* PUBLIC: const token_t *));
*
* normctx The normalizer to be initialized
* parser Error messages will be written here
* dbnum This is the database that must must be used
* type "view", "trigger", or "index"
* name Name of the view, trigger, or index
*/
int
__ref_normalizer_ctx_init(normctx, parser, dbnum, type, name)
ref_normalizer_ctx_t *normctx;
parser_t *parser;
int dbnum;
const char *type;
const token_t *name;
{
DBSQL *dbp;
if (dbnum < 0 || dbnum == 1)
return 0;
dbp = parser->db;
DBSQL_ASSERT(dbp->nDb > dbnum);
normctx->pParse = parser;
normctx->zDb = dbp->aDb[dbnum].zName;
normctx->zType = type;
normctx->pName = name;
return 1;
}
/*
* __ref_normalize_src_list --
* The following set of routines walk through the parse tree and assign
* a specific database to all table references where the database name
* was left unspecified in the original SQL statement. The normctx
* structure must have been initialized by a prior call to
* __ref_normalizer_ctx_init().
*
* These routines are used to make sure that an index, trigger, or
* view in one database does not refer to objects in a different database.
* (Exception: indices, triggers, and views in the TEMP database are
* allowed to refer to anything.) If a reference is explicitly made
* to an object in a different database, an error message is added to
* parser->zErrMsg and these routines return non-zero. If everything
* checks out, these routines return 0.
*
* PUBLIC: int __ref_normalize_src_list __P((ref_normalizer_ctx_t *,
* PUBLIC: src_list_t *));
*
* normctx Context of the normalization
* src_list The source list to check and modify
*/
int __ref_normalize_src_list(normctx, src_list)
ref_normalizer_ctx_t *normctx;
src_list_t *src_list;
{
int i;
const char *db;
DBSQL *dbp = normctx->pParse->db;
if (src_list == 0)
return 0;
db = normctx->zDb;
for (i = 0; i < src_list->nSrc; i++) {
if (src_list->a[i].zDatabase == 0) {
__dbsql_strdup(dbp, db, &src_list->a[i].zDatabase);
} else if (strcasecmp(src_list->a[i].zDatabase, db) != 0) {
char *name;
__dbsql_strndup(dbp, normctx->pName->z, &name,
normctx->pName->n);
__error_msg(normctx->pParse, "%s %z cannot reference "
"objects in database %s", normctx->zType,
name, src_list->a[i].zDatabase);
return 1;
}
if (__ref_normalize_select(normctx, src_list->a[i].pSelect))
return 1;
if (__ref_normalize_expr(normctx, src_list->a[i].pOn))
return 1;
}
return 0;
}
/*
* __ref_normalize_select --
*
* PUBLIC: int __ref_normalize_select __P((ref_normalizer_ctx_t *,
* PUBLIC: select_t *));
*
* normctx Context of the normalization
* select The SELECT statement to be fixed to one
* database
*/
int
__ref_normalize_select(ref_normalizer_ctx_t* normctx, select_t* select)
{
while (select) {
if (__ref_normalize_expr_list(normctx, select->pEList)) {
return 1;
}
if (__ref_normalize_src_list(normctx, select->pSrc)) {
return 1;
}
if (__ref_normalize_expr(normctx, select->pWhere)) {
return 1;
}
if (__ref_normalize_expr(normctx, select->pHaving)) {
return 1;
}
select = select->pPrior;
}
return 0;
}
/*
* __ref_normalize_expr --
*
* PUBLIC: int __ref_normalize_expr __P((ref_normalizer_ctx_t *,
* PUBLIC: expr_t *));
*
* normctx Context of the normalization
* expr The expr_t to be fixed to one database
*/
int __ref_normalize_expr(normctx, expr)
ref_normalizer_ctx_t *normctx;
expr_t *expr;
{
while (expr) {
if (__ref_normalize_select(normctx, expr->pSelect)) {
return 1;
}
if (__ref_normalize_expr_list(normctx, expr->pList)) {
return 1;
}
if (__ref_normalize_expr(normctx, expr->pRight)) {
return 1;
}
expr = expr->pLeft;
}
return 0;
}
/*
* __ref_normalize_expr_list --
*
* PUBLIC: int __ref_normalize_expr_list __P((ref_normalizer_ctx_t *,
* PUBLIC: expr_list_t *));
*
* normctx Context of the normalization
* expr The expression to be fixed to one database
*/
int
__ref_normalize_expr_list(ref_normalizer_ctx_t* normctx, expr_list_t* list)
{
int i;
if (list == 0)
return 0;
for (i = 0; i < list->nExpr; i++) {
if (__ref_normalize_expr(normctx, list->a[i].pExpr)) {
return 1;
}
}
return 0;
}
/*
* __ref_normalize_trigger_step --
*
* PUBLIC: int __ref_normalize_trigger_step __P((ref_normalizer_ctx_t *,
* PUBLIC: trigger_step_t *));
*
* normctx Context of the normalization
* expr The trigger step to be fixed to one database
*/
int __ref_normalize_trigger_step(normctx, step)
ref_normalizer_ctx_t *normctx;
trigger_step_t *step;
{
while (step) {
if (__ref_normalize_select(normctx, step->pSelect)) {
return 1;
}
if (__ref_normalize_expr(normctx, step->pWhere)) {
return 1;
}
if (__ref_normalize_expr_list(normctx, step->pExprList)) {
return 1;
}
step = step->pNext;
}
return 0;
}

View file

@ -1,275 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains code used to implement the __api_set_auth_callback()
* API. This facility is an optional feature of the library. Embedded
* systems that do not need this facility may omit it by reconfiguring
* with '--disable-auth'. Then recompile the entire library.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#ifndef DBSQL_OMIT_AUTHORIZATION
/*
* Set or clear the access authorization function.
* The access authorization function is be called during the compilation
* phase to verify that the user has read and/or write access permission
* on various fields of the database. The first argument to the auth
* function is a copy of the 3rd argument to this routine. The second
* argument to the auth function is one of these constants:
*
* DBSQL_COPY
* DBSQL_CREATE_INDEX
* DBSQL_CREATE_TABLE
* DBSQL_CREATE_TEMP_INDEX
* DBSQL_CREATE_TEMP_TABLE
* DBSQL_CREATE_TEMP_TRIGGER
* DBSQL_CREATE_TEMP_VIEW
* DBSQL_CREATE_TRIGGER
* DBSQL_CREATE_VIEW
* DBSQL_DELETE
* DBSQL_DROP_INDEX
* DBSQL_DROP_TABLE
* DBSQL_DROP_TEMP_INDEX
* DBSQL_DROP_TEMP_TABLE
* DBSQL_DROP_TEMP_TRIGGER
* DBSQL_DROP_TEMP_VIEW
* DBSQL_DROP_TRIGGER
* DBSQL_DROP_VIEW
* DBSQL_INSERT
* DBSQL_PRAGMA
* DBSQL_READ
* DBSQL_SELECT
* DBSQL_TRANSACTION
* DBSQL_UPDATE
*
* The third and fourth arguments to the auth function are the name of
* the table and the column that are being accessed. The auth function
* should return either DBSQL_SUCCESS, DBSQL_DENY, or DBSQL_IGNORE. If
* DBSQL_SUCCESS is returned, it means that access is allowed. DBSQL_DENY
* means that the SQL statement will never-run - the dbsql_exec() call
* will return with an error. DBSQL_IGNORE means that the SQL statement
* should run but attempts to read the specified column will return NULL
* and attempts to write the column will be ignored.
*
* Setting the auth function to NULL disables this hook. The default
* setting of the auth function is NULL.
*
* PUBLIC: int __api_set_authorizer __P((DBSQL *,
* PUBLIC: int (*auth)(void*,int,const char*, const char*,const char*,
* PUBLIC: const char*), void *));
*/
int __api_set_authorizer(dbp, auth, arg)
DBSQL *dbp;
int (*auth)(void*,int,const char*,const char*,const char*,const char*);
void *arg;
{
dbp->auth = auth;
dbp->pAuthArg = arg;
return DBSQL_SUCCESS;
}
/*
* __auth_bad_return_code --
* Write an error message into pParse->zErrMsg that explains that the
* user-supplied authorization function returned an illegal value.
*
* STATIC: static void __auth_bad_return_code __P((parser_t *, int));
*/
static void
__auth_bad_return_code(parser_t* parser, int rc)
{
char buf[20];
sprintf(buf, "(%d)", rc);
__str_append(&parser->zErrMsg, "illegal return value ",
buf, " from the authorization function - ",
"should be DBSQL_SUCCESS, DBSQL_IGNORE, or DBSQL_DENY",
(char*)0);
parser->nErr++;
parser->rc = DBSQL_MISUSE;
}
/*
* __auth_read --
* The 'expr' should be a TK_COLUMN expression. The table referred to
* is in 'tab_list' or else it is the NEW or OLD table of a trigger.
* Check to see if it is OK to read this particular column.
*
* If the auth function returns DBSQL_IGNORE, change the TK_COLUMN
* instruction into a TK_NULL. If the auth function returns DBSQL_DENY,
* then generate an error.
*
* PUBLIC: void __auth_read __P((parser_t *, expr_t *, src_list_t *));
*
* parser The parser context
* expr The expression to check authorization on
* tab_list All table that expr might refer to
*/
void
__auth_read(parser_t* parser, expr_t* expr, src_list_t* tab_list)
{
int rc;
DBSQL *dbp = parser->db;
table_t *table; /* The table being read */
const char *col; /* Name of the column of the table */
int src; /* Index in tab_list->a[] of table being read */
const char *databasename; /* Name of database being accessed */
trigger_stack_t *stack; /* The stack of current triggers */
if (dbp->auth == 0)
return;
DBSQL_ASSERT(expr->op == TK_COLUMN);
for (src = 0; src < tab_list->nSrc; src++) {
if (expr->iTable == tab_list->a[src].iCursor)
break;
}
if (src >= 0 && src < tab_list->nSrc) {
table = tab_list->a[src].pTab;
} else {
/*
* This must be an attempt to read the NEW or OLD pseudo-tables
* of a trigger.
*/
stack = parser->trigStack;
DBSQL_ASSERT(stack != 0);
DBSQL_ASSERT(expr->iTable == stack->newIdx ||
expr->iTable == stack->oldIdx);
table = stack->pTab;
}
if (table == 0)
return;
if (expr->iColumn >= 0) {
DBSQL_ASSERT(expr->iColumn < table->nCol);
col = table->aCol[expr->iColumn].zName;
} else if (table->iPKey >= 0) {
DBSQL_ASSERT(table->iPKey < table->nCol);
col = table->aCol[table->iPKey].zName;
} else {
col = "ROWID";
}
DBSQL_ASSERT(expr->iDb < dbp->nDb);
databasename = dbp->aDb[expr->iDb].zName;
rc = dbp->auth(dbp->pAuthArg, DBSQL_READ, table->zName,
col, databasename, parser->zAuthContext);
if (rc == DBSQL_IGNORE) {
expr->op = TK_NULL;
} else if (rc == DBSQL_DENY) {
if (dbp->nDb > 2 || expr->iDb != 0) {
__str_append(&parser->zErrMsg,"access to ",
databasename, ".", table->zName, ".",
col, " is prohibited", (char*)0);
} else {
__str_append(&parser->zErrMsg,"access to ",
table->zName, ".", col, " is prohibited",
(char*)0);
}
parser->nErr++;
parser->rc = DBSQL_AUTH;
} else if (rc != DBSQL_SUCCESS) {
__auth_bad_return_code(parser, rc);
}
}
/*
* __auth_check --
* Do an authorization check using the code and arguments given. Return
* either DBSQL_SUCCESS (zero) or DBSQL_IGNORE or DBSQL_DENY. If
* DBSQL_DENY is returned, then the error count and error message in
* parser are modified appropriately.
*
* PUBLIC: int __auth_check __P((parser_t *, int, const char *, const char *,
* PUBLIC: const char *));
*/
int
__auth_check(parser, code, arg1, arg2, arg3)
parser_t *parser;
int code;
const char *arg1;
const char *arg2;
const char *arg3;
{
int rc;
DBSQL *dbp = parser->db;
if (dbp->auth == 0) {
return DBSQL_SUCCESS;
}
rc = dbp->auth(dbp->pAuthArg, code, arg1, arg2, arg3,
parser->zAuthContext);
if (rc == DBSQL_DENY) {
__str_append(&parser->zErrMsg, "not authorized",
(char*)0);
parser->rc = DBSQL_AUTH;
parser->nErr++;
} else if (rc != DBSQL_SUCCESS && rc != DBSQL_IGNORE) {
rc = DBSQL_DENY;
__auth_bad_return_code(parser, rc);
}
return rc;
}
/*
* __auth_context_push --
* Push an authorization context. After this routine is called, the
* arg3 argument to authorization callbacks will be context until
* popped. Or if parser==0, this routine is a no-op.
*
* PUBLIC: void __auth_context_push __P((parser_t *, auth_context_t *,
* PUBLIC: const char *));
*/
void __auth_context_push(parser, authctx, context)
parser_t *parser;
auth_context_t *authctx;
const char *context;
{
authctx->pParse = parser;
if (parser) {
authctx->zAuthContext = parser->zAuthContext;
parser->zAuthContext = context;
}
}
/*
* __auth_context_pop --
* Pop an authorization context that was previously pushed
* by __auth_context_push.
*
* PUBLIC: void __auth_context_pop __P((auth_context_t *));
*/
void
__auth_context_pop(auth_context_t* authctx)
{
if (authctx->pParse) {
authctx->pParse->zAuthContext = authctx->zAuthContext;
authctx->pParse = 0;
}
}
#else
/* TODO what is the difference between DBSQL_OMIT_AUTHORIZATION and
DBSQL_NO_AUTH? Which one should be used here? Setup a test case for this.*/
# define __auth_check(a,b,c,d,e) DBSQL_SUCCESS
#endif /* !defined(DBSQL_OMIT_AUTHORIZATION) */

File diff suppressed because it is too large Load diff

View file

@ -1,150 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains code used to implement the COPY command.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __copy --
* The COPY command is for compatibility with PostgreSQL and specificially
* for the ability to read the output of pg_dump. The format is as
* follows:
*
* COPY table FROM file [USING DELIMITERS string]
*
* "table" is an existing table name. We will read lines of code from
* file to fill this table with data. File might be "stdin". The
* optional delimiter string identifies the field separators. The
* default is a tab.
*
* PUBLIC: void __copy __P((parser_t *, src_list_t *, token_t *,
* PUBLIC: token_t *, int));
*
* parser The parser context
* table_name The name of the table into which we will insert
* filename The file from which to obtain information
* delimiter Use this as the field delimiter
* on_error What to do if a constraint fails
*/
void __copy(parser, table_name, filename, delimiter, on_error)
parser_t *parser;
src_list_t *table_name;
token_t *filename;
token_t *delimiter;
int on_error;
{
table_t *table;
int i;
vdbe_t *v;
int addr, end;
index_t *index;
char *file = 0;
const char *db_name;
DBSQL *db = parser->db;
if (parser->rc != DBSQL_SUCCESS)
goto copy_cleanup;
DBSQL_ASSERT(table_name->nSrc == 1);
table = __src_list_lookup(parser, table_name);
if (table==0 || __is_table_read_only(parser, table, 0))
goto copy_cleanup;
__dbsql_strndup(parser->db, filename->z, &file, filename->n);
__str_unquote(file);
DBSQL_ASSERT(table->iDb < db->nDb);
db_name = db->aDb[table->iDb].zName;
if (__auth_check(parser, DBSQL_INSERT, table->zName, 0, db_name) ||
__auth_check(parser, DBSQL_COPY, table->zName, file, db_name)) {
goto copy_cleanup;
}
v = __parser_get_vdbe(parser);
if (v) {
__vdbe_prepare_write(parser, 1, table->iDb);
addr = __vdbe_add_op(v, OP_FileOpen, 0, 0);
__vdbe_change_p3(v, addr, filename->z, filename->n);
__vdbe_dequote_p3(v, addr);
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, 0, table->tnum);
__vdbe_change_p3(v, -1, table->zName, P3_STATIC);
for(i = 1, index = table->pIndex; index;
index=index->pNext, i++) {
DBSQL_ASSERT(index->iDb == 1 || index->iDb == table->iDb);
__vdbe_add_op(v, OP_Integer, index->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, i, index->tnum);
__vdbe_change_p3(v, -1, index->zName, P3_STATIC);
}
if (db->flags & DBSQL_CountRows) {
/* Initialize the row count */
__vdbe_add_op(v, OP_Integer, 0, 0);
}
end = __vdbe_make_label(v);
addr = __vdbe_add_op(v, OP_FileRead, table->nCol, end);
if (delimiter) {
__vdbe_change_p3(v, addr, delimiter->z, delimiter->n);
__vdbe_dequote_p3(v, addr);
} else {
__vdbe_change_p3(v, addr, "\t", 1);
}
if (table->iPKey >= 0) {
__vdbe_add_op(v, OP_FileColumn, table->iPKey, 0);
__vdbe_add_op(v, OP_MustBeInt, 0, 0);
} else {
__vdbe_add_op(v, OP_NewRecno, 0, 0);
}
for(i = 0; i < table->nCol; i++) {
if (i == table->iPKey) {
/*
* The integer primary key column is filled
* with NULL since its value is always pulled
* from the record number.
*/
__vdbe_add_op(v, OP_String, 0, 0);
} else {
__vdbe_add_op(v, OP_FileColumn, i, 0);
}
}
__generate_constraint_checks(parser, table, 0, 0,
(table->iPKey >= 0), 0, on_error,
addr);
__complete_insertion(parser, table, 0, 0, 0, 0, -1);
if ((db->flags & DBSQL_CountRows) != 0) {
/* Increment row count */
__vdbe_add_op(v, OP_AddImm, 1, 0);
}
__vdbe_add_op(v, OP_Goto, 0, addr);
__vdbe_resolve_label(v, end);
__vdbe_add_op(v, OP_Noop, 0, 0);
__vdbe_conclude_write(parser);
if (db->flags & DBSQL_CountRows) {
__vdbe_add_op(v, OP_ColumnName, 0, 0);
__vdbe_change_p3(v, -1, "rows inserted", P3_STATIC);
__vdbe_add_op(v, OP_Callback, 1, 0);
}
}
copy_cleanup:
__src_list_delete(table_name);
__dbsql_free(parser->db, file);
return;
}

File diff suppressed because it is too large Load diff

View file

@ -1,491 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains C code routines that are called by the parser
* to handle DELETE FROM statements.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __src_list_lookup --
* Look up every table that is named in 'src'. If any table is not found,
* add an error message to parse->zErrMsg and return NULL. If all tables
* are found, return a pointer to the last table.
*
* PUBLIC: table_t *__src_list_lookup __P((parser_t *, src_list_t *));
*/
table_t *
__src_list_lookup(parser_t* parser, src_list_t* src)
{
table_t *table = 0;
int i;
for (i = 0; i < src->nSrc; i++) {
const char *tb_name = src->a[i].zName;
const char *db_name = src->a[i].zDatabase;
table = __locate_table(parser, tb_name, db_name);
src->a[i].pTab = table;
}
return table;
}
/*
* __is_table_read_only --
* Check to make sure the given table is writable. If it is not
* writable, generate an error message and return 1. If it is
* writable return 0;
*
* PUBLIC: int __is_table_read_only __P((parser_t *, table_t *, int));
*/
int
__is_table_read_only(parser_t* parser, table_t* table, int views_ok)
{
if (table->readOnly) {
__error_msg(parser, "table %s may not be modified",
table->zName);
return 1;
}
if (!views_ok && table->pSelect) {
__error_msg(parser, "cannot modify %s because it is a view",
table->zName);
return 1;
}
return 0;
}
/*
* __delete_from --
* Process a DELETE FROM statement.
*
* PUBLIC: void __delete_from __P((parser_t *, src_list_t *, expr_t *));
*
* parser The parser context
* list The table from which we should delete things
* where The WHERE clause. May be null.
*/
void __delete_from(parser, list, where)
parser_t *parser;
src_list_t *list;
expr_t *where;
{
vdbe_t *v; /* The virtual database engine */
table_t *table; /* The table from which records will be deleted */
const char *name; /* Name of database holding 'table' */
int end, addr; /* A couple addresses of generated code */
int i; /* Loop counter */
where_info_t *info; /* Information about the WHERE clause */
index_t *idx; /* For looping over indices of the table */
int cur; /* VDBE Cursor number for 'table' */
DBSQL *dbp; /* Main database structure */
int view; /* True if attempting to delete from a view */
auth_context_t context;/* Authorization context */
int row_triggers_exist = 0;/* True if any triggers exist */
int before_triggers;/* True if there are BEFORE triggers */
int after_triggers; /* True if there are AFTER triggers */
int old_idx = -1; /* Cursor for the OLD table of AFTER triggers */
context.pParse = 0;
if (parser->nErr || parser->rc == ENOMEM) {
list = 0;
goto delete_from_cleanup;
}
dbp = parser->db;
DBSQL_ASSERT(list->nSrc == 1);
/*
* Locate the table which we want to delete. This table has to be
* put in an src_list_t structure because some of the subroutines we
* will be calling are designed to work with multiple tables and expect
* an src_list_t* parameter instead of just a table_t* parameter.
*/
table = __src_list_lookup(parser, list);
if (table == 0)
goto delete_from_cleanup;
before_triggers = __triggers_exist(parser, table->pTrigger,
TK_DELETE, TK_BEFORE, TK_ROW, 0);
after_triggers = __triggers_exist(parser, table->pTrigger,
TK_DELETE, TK_AFTER, TK_ROW, 0);
row_triggers_exist = (before_triggers || after_triggers);
view = (table->pSelect != 0);
if (__is_table_read_only(parser, table, before_triggers)) {
goto delete_from_cleanup;
}
DBSQL_ASSERT(table->iDb < dbp->nDb);
name = dbp->aDb[table->iDb].zName;
if (__auth_check(parser, DBSQL_DELETE, table->zName, 0, name)) {
goto delete_from_cleanup;
}
/*
* If pTab is really a view, make sure it has been initialized.
*/
if (view && __view_get_column_names(parser, table)) {
goto delete_from_cleanup;
}
/*
* Allocate a cursor used to store the old.* data for a trigger.
*/
if (row_triggers_exist) {
old_idx = parser->nTab++;
}
/*
* Resolve the column names in all the expressions.
*/
DBSQL_ASSERT(list->nSrc == 1);
cur = list->a[0].iCursor = parser->nTab++;
if (where) {
if (__expr_resolve_ids(parser, list, 0, where)) {
goto delete_from_cleanup;
}
if (__expr_check(parser, where, 0, 0)) {
goto delete_from_cleanup;
}
}
/*
* Start the view context.
*/
if (view) {
__auth_context_push(parser, &context, table->zName);
}
/*
* Begin generating code.
*/
v = __parser_get_vdbe(parser);
if (v == 0) {
goto delete_from_cleanup;
}
__vdbe_prepare_write(parser, row_triggers_exist, table->iDb);
/*
* If we are trying to delete from a view, construct that view into
* a temporary table.
*/
if (view) {
select_t *vsel = __select_dup(table->pSelect);
__select(parser, vsel, SRT_TempTable, cur, 0, 0, 0);
__select_delete(vsel);
}
/*
* Initialize the counter of the number of rows deleted, if
* we are counting rows.
*/
if (dbp->flags & DBSQL_CountRows) {
__vdbe_add_op(v, OP_Integer, 0, 0);
}
/*
* Special case: A DELETE without a WHERE clause deletes everything.
* It is easier just to erase the whole table. Note, however, that
* this means that the row change count will be incorrect.
*/
if (where == 0 && !row_triggers_exist) {
if (dbp->flags & DBSQL_CountRows) {
/*
* If counting rows deleted, just count the total
* number of entries in the table.
*/
int end_of_loop = __vdbe_make_label(v);
int addr;
if (!view) {
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenRead, cur,
table->tnum);
}
__vdbe_add_op(v, OP_Rewind, cur,
(__vdbe_current_addr(v) + 2));
addr = __vdbe_add_op(v, OP_AddImm, 1, 0);
__vdbe_add_op(v, OP_Next, cur, addr);
__vdbe_resolve_label(v, end_of_loop);
__vdbe_add_op(v, OP_Close, cur, 0);
}
if (!view) {
__vdbe_add_op(v, OP_Clear, table->tnum, table->iDb);
for (idx = table->pIndex; idx; idx = idx->pNext) {
__vdbe_add_op(v, OP_Clear, idx->tnum,
idx->iDb);
}
}
} else {
/*
* The usual case: There is a WHERE clause so we have to
* scan through the table and pick which records to delete.
*/
/*
* Begin the database scan.
*/
info = __where_begin(parser, list, where, 1, 0);
if (info == 0)
goto delete_from_cleanup;
/*
* Remember the key of every item to be deleted.
*/
__vdbe_add_op(v, OP_ListWrite, 0, 0);
if (dbp->flags & DBSQL_CountRows) {
__vdbe_add_op(v, OP_AddImm, 1, 0);
}
/*
* End the database scan loop.
*/
__where_end(info);
/*
* Open the pseudo-table used to store OLD if there are
* triggers.
*/
if (row_triggers_exist) {
__vdbe_add_op(v, OP_OpenPseudo, old_idx, 0);
}
/*
* Delete every item whose key was written to the list
* during the database scan. We have to delete items
* after the scan is complete because deleting an item
* can change the scan order.
*/
__vdbe_add_op(v, OP_ListRewind, 0, 0);
end = __vdbe_make_label(v);
/*
* This is the beginning of the delete loop when there are
* row triggers.
*/
if (row_triggers_exist) {
addr = __vdbe_add_op(v, OP_ListRead, 0, end);
__vdbe_add_op(v, OP_Dup, 0, 0);
if (!view) {
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenRead, cur,
table->tnum);
}
__vdbe_add_op(v, OP_MoveTo, cur, 0);
__vdbe_add_op(v, OP_Recno, cur, 0);
__vdbe_add_op(v, OP_RowData, cur, 0);
__vdbe_add_op(v, OP_PutIntKey, old_idx, 0);
if (!view) {
__vdbe_add_op(v, OP_Close, cur, 0);
}
__code_row_trigger(parser, TK_DELETE, 0, TK_BEFORE,
table, -1, old_idx,
((parser->trigStack) ?
parser->trigStack->orconf :
OE_Default), addr);
}
if (!view) {
/*
* Open cursors for the table we are deleting from
* and all its indices. If there are row triggers,
* this happens inside the OP_ListRead loop because
* the cursor have to all be closed before the trigger
* fires. If there are no row triggers, the cursors
* are opened only once on the outside the loop.
*/
parser->nTab = cur + 1;
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, cur, table->tnum);
for (i = 1, idx = table->pIndex; idx;
i++, idx = idx->pNext) {
__vdbe_add_op(v, OP_Integer, idx->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, parser->nTab++,
idx->tnum);
}
/*
* This is the beginning of the delete loop when
* there are no row triggers.
*/
if (!row_triggers_exist) {
addr = __vdbe_add_op(v, OP_ListRead, 0, end);
}
/*
* Delete the row.
*/
__generate_row_delete(dbp, v, table, cur,
(parser->trigStack == 0));
}
/*
* If there are row triggers, close all cursors then invoke
* the AFTER triggers.
*/
if (row_triggers_exist) {
if (!view) {
for(i = 1, idx = table->pIndex; idx;
i++, idx = idx->pNext) {
__vdbe_add_op(v, OP_Close, cur + i,
idx->tnum);
}
__vdbe_add_op(v, OP_Close, cur, 0);
}
__code_row_trigger(parser, TK_DELETE, 0, TK_AFTER,
table, -1, old_idx,
((parser->trigStack) ?
parser->trigStack->orconf :
OE_Default), addr);
}
/*
* End of the delete loop.
*/
__vdbe_add_op(v, OP_Goto, 0, addr);
__vdbe_resolve_label(v, end);
__vdbe_add_op(v, OP_ListReset, 0, 0);
/*
* Close the cursors after the loop if there are no row
* triggers.
*/
if (!row_triggers_exist) {
for (i = 1, idx = table->pIndex; idx;
i++, idx = idx->pNext) {
__vdbe_add_op(v, OP_Close, cur + i, idx->tnum);
}
__vdbe_add_op(v, OP_Close, cur, 0);
parser->nTab = cur;
}
}
__vdbe_conclude_write(parser);
/*
* Return the number of rows that were deleted.
*/
if (dbp->flags & DBSQL_CountRows) {
__vdbe_add_op(v, OP_ColumnName, 0, 0);
__vdbe_change_p3(v, -1, "rows deleted", P3_STATIC);
__vdbe_add_op(v, OP_Callback, 1, 0);
}
delete_from_cleanup:
__auth_context_pop(&context);
__src_list_delete(list);
__expr_delete(where);
return;
}
/*
* __generate_row_delete --
* This routine generates VDBE code that causes a single row of a
* single table to be deleted.
*
* The VDBE must be in a particular state when this routine is called.
* These are the requirements:
*
* 1. A read/write cursor pointing to 'table', the table containing
* the row to be deleted, must be opened as cursor number "base".
*
* 2. Read/write cursors for all indices of pTab must be open as
* cursor number base+i for the i-th index.
*
* 3. The record number of the row to be deleted must be on the top
* of the stack.
*
* This routine pops the top of the stack to remove the record number
* and then generates code to remove both the table record and all index
* entries that point to that record.
*
* PUBLIC: void __generate_row_delete __P((DBSQL *, vdbe_t *, table_t *,
* PUBLIC: int, int));
*
* dbp The database containing the index
* v Generate code into this VDBE
* table Table containing the row to be deleted
* cur Cursor number for the table
* count Increment the row change counter
*/
void __generate_row_delete(dbp, v, table, cur, count)
DBSQL *dbp;
vdbe_t *v;
table_t *table;
int cur;
int count;
{
int addr;
addr = __vdbe_add_op(v, OP_NotExists, cur, 0);
__generate_row_index_delete(dbp, v, table, cur, 0);
__vdbe_add_op(v, OP_Delete, cur, count);
__vdbe_change_p2(v, addr, __vdbe_current_addr(v));
}
/*
* __generate_row_index_delete --
* This routine generates VDBE code that causes the deletion of all
* index entries associated with a single row of a single table.
*
* The VDBE must be in a particular state when this routine is called.
* These are the requirements:
*
* 1. A read/write cursor pointing to 'table', the table containing
* the row to be deleted, must be opened as cursor number 'cur'.
*
* 2. Read/write cursors for all indices of 'table' must be open as
* cursor number cur+i for the i-th index.
*
* 3. The 'cur' cursor must be pointing to the row that is to be
* deleted.
*
* PUBLIC: void __generate_row_index_delete __P((DBSQL *, vdbe_t *,
* PUBLIC: table_t *, int, char *));
*
* dbp The database containing the index
* v Generate code into this VDBE
* table Table containing the row to be deleted
* cur Cursor number for the table
* idx_used Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0
*/
void __generate_row_index_delete(dbp, v, table, cur, idx_used)
DBSQL *dbp;
vdbe_t *v;
table_t *table;
int cur;
char *idx_used;
{
int i;
index_t *idx;
for (i = 1, idx = table->pIndex; idx; i++, idx = idx->pNext) {
int j;
if (idx_used != 0 && idx_used[i-1] == 0)
continue;
__vdbe_add_op(v, OP_Recno, cur, 0);
for (j = 0; j < idx->nColumn; j++) {
int n = idx->aiColumn[j];
if (n == table->iPKey) {
__vdbe_add_op(v, OP_Dup, j, 0);
} else {
__vdbe_add_op(v, OP_Column, cur, n);
}
}
__vdbe_add_op(v, OP_MakeIdxKey, idx->nColumn, 0);
__add_idx_key_type(v, idx);
__vdbe_add_op(v, OP_IdxDelete, cur + i, 0);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,387 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains code used to implement the PRAGMA command.
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <ctype.h>
#endif
#include "dbsql_int.h"
/*
* __get_boolean --
* Interpret the given string as a boolean value.
*
* STATIC: static int __get_boolean __P((char *));
*/
static int
__get_boolean(char* z)
{
static char *true[] = { "yes", "on", "true" };
int i;
if (z[0] == 0)
return 0;
if (isdigit(z[0]) || (z[0]=='-' && isdigit(z[1]))) {
return atoi(z);
}
for(i = 0; i < sizeof(true) / sizeof(true[0]); i++) {
if (strcasecmp(z, true[i]) == 0)
return 1;
}
return 0;
}
/*
* __get_safety_level --
* Interpret the given string as a safety level. Return 0 for OFF,
* 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
* unrecognized string argument.
*
* Note that the values returned are one less that the values that
* should be passed into __sm_set_safety_level(). This is done
* to support legacy SQL code. The safety level used to be boolean
* and older scripts may have used numbers 0 for OFF and 1 for ON.
*
* STATIC: static int __get_safety_level __P((char *));
*/
static int
__get_safety_level(char* z)
{
static const struct {
const char *word;
int val;
} key[] = {
{ "no", 0 },
{ "off", 0 },
{ "false", 0 },
{ "yes", 1 },
{ "on", 1 },
{ "true", 1 },
{ "full", 2 },
};
int i;
if (z[0] == 0)
return 1;
if (isdigit(z[0]) || (z[0] == '-' && isdigit(z[1]))) {
return atoi(z);
}
for (i = 0; i < sizeof(key)/sizeof(key[0]); i++) {
if (strcasecmp(z,key[i].word) == 0)
return key[i].val;
}
return 1;
}
/*
* __pragma --
* Process a pragma statement.
*
* Pragmas are of this form:
*
* PRAGMA id = value
*
* The identifier might also be a string. The value is a string, and
* identifier, or a number. If 'minus_p' is true, then the value is
* a number that was preceded by a minus sign.
*
* PUBLIC: void __pragma __P((parser_t *, token_t *, token_t *, int));
*/
void
__pragma(parser_t* parser, token_t* left, token_t* right, int minus_p)
{
char *left_name = 0;
char *right_name = 0;
DBSQL *dbp = parser->db;
vdbe_t *v = __parser_get_vdbe(parser);
if (v == 0)
return;
__dbsql_strndup(dbp, left->z, &left_name, left->n);
__str_unquote(left_name);
if (minus_p) {
right_name = 0;
__str_nappend(&right_name, "-", 1, right->z, right->n, NULL);
} else {
__dbsql_strndup(dbp, right->z, &right_name, right->n);
__str_unquote(right_name);
}
if (__auth_check(parser, DBSQL_PRAGMA, left_name, right_name, NULL)) {
__dbsql_free(dbp, left_name);
__dbsql_free(dbp, right_name);
return;
}
/*
* PRAGMA trigger_overhead_test
*/
if (strcasecmp(left_name, "trigger_overhead_test") == 0) {
if (__get_boolean(right_name)) {
always_code_trigger_setup = 1;
} else {
always_code_trigger_setup = 0;
}
} else
/*
* PRAGMA vdbe_trace
*/
if (strcasecmp(left_name, "vdbe_trace") == 0) {
if (__get_boolean(right_name)) {
dbp->flags |= DBSQL_VdbeTrace;
} else {
dbp->flags &= ~DBSQL_VdbeTrace;
}
} else
/*
* PRAGMA full_column_names
*/
if (strcasecmp(left_name, "full_column_names") == 0) {
if (__get_boolean(right_name)) {
dbp->flags |= DBSQL_FullColNames;
} else {
dbp->flags &= ~DBSQL_FullColNames;
}
} else
/*
* PRAGMA show_datatypes
*/
if (strcasecmp(left_name, "show_datatypes") == 0) {
if( __get_boolean(right_name)) {
dbp->flags |= DBSQL_ReportTypes;
} else {
dbp->flags &= ~DBSQL_ReportTypes;
}
} else
/*
* PRAGMA count_changes
*/
if (strcasecmp(left_name, "count_changes") == 0) {
if (__get_boolean(right_name)) {
dbp->flags |= DBSQL_CountRows;
} else {
dbp->flags &= ~DBSQL_CountRows;
}
} else
/*
* PRAGMA empty_result_callbacks
*/
if (strcasecmp(left_name, "empty_result_callbacks") == 0) {
if ( __get_boolean(right_name)) {
dbp->flags |= DBSQL_NullCallback;
} else {
dbp->flags &= ~DBSQL_NullCallback;
}
} else
/*
* PRAGMA table_info
*/
if (strcasecmp(left_name, "table_info") == 0) {
table_t *table;
table = __find_table(dbp, right_name, 0);
if (table) {
static vdbe_op_t table_info_preface[] = {
{ OP_ColumnName, 0, 0, "cid"},
{ OP_ColumnName, 1, 0, "name"},
{ OP_ColumnName, 2, 0, "type"},
{ OP_ColumnName, 3, 0, "notnull"},
{ OP_ColumnName, 4, 0, "dflt_value"},
{ OP_ColumnName, 5, 0, "pk"},
};
int i;
__vdbe_add_op_list(v, ARRAY_SIZE(table_info_preface),
table_info_preface);
__view_get_column_names(parser, table);
for (i = 0; i < table->nCol; i++) {
__vdbe_add_op(v, OP_Integer, i, 0);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1, table->aCol[i].zName,
P3_STATIC);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1,
table->aCol[i].zType ?
table->aCol[i].zType :
"numeric", P3_STATIC);
__vdbe_add_op(v, OP_Integer,
table->aCol[i].notNull, 0);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1, table->aCol[i].zDflt,
P3_STATIC);
__vdbe_add_op(v, OP_Integer,
table->aCol[i].isPrimKey, 0);
__vdbe_add_op(v, OP_Callback, 6, 0);
}
}
} else
/*
* PRAGMA index_info
*/
if (strcasecmp(left_name, "index_info") == 0) {
index_t *index;
table_t *table;
index = __find_index(dbp, right_name, 0);
if (index) {
static vdbe_op_t table_info_preface[] = {
{ OP_ColumnName, 0, 0, "seqno"},
{ OP_ColumnName, 1, 0, "cid"},
{ OP_ColumnName, 2, 0, "name"},
};
int i;
table = index->pTable;
__vdbe_add_op_list(v, ARRAY_SIZE(table_info_preface),
table_info_preface);
for (i = 0; i < index->nColumn; i++) {
int cnum = index->aiColumn[i];
__vdbe_add_op(v, OP_Integer, i, 0);
__vdbe_add_op(v, OP_Integer, cnum, 0);
__vdbe_add_op(v, OP_String, 0, 0);
DBSQL_ASSERT(table->nCol > cnum);
__vdbe_change_p3(v, -1,
table->aCol[cnum].zName,
P3_STATIC);
__vdbe_add_op(v, OP_Callback, 3, 0);
}
}
} else
/*
* PRAGMA index_list
*/
if (strcasecmp(left_name, "index_list") == 0) {
index_t *index;
table_t *table;
table = __find_table(dbp, right_name, 0);
if (table) {
v = __parser_get_vdbe(parser);
index = table->pIndex;
}
if (table && index) {
int i = 0;
static vdbe_op_t index_list_preface[] = {
{ OP_ColumnName, 0, 0, "seq"},
{ OP_ColumnName, 1, 0, "name"},
{ OP_ColumnName, 2, 0, "unique"},
};
__vdbe_add_op_list(v, ARRAY_SIZE(index_list_preface),
index_list_preface);
while(index) {
__vdbe_add_op(v, OP_Integer, i, 0);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1, index->zName,
P3_STATIC);
__vdbe_add_op(v, OP_Integer,
index->onError != OE_None, 0);
__vdbe_add_op(v, OP_Callback, 3, 0);
++i;
index = index->pNext;
}
}
} else
/*
* PRAGMA foreign_key_list
*/
if (strcasecmp(left_name, "foreign_key_list") == 0) {
foreign_key_t *fk;
table_t *table;
table = __find_table(dbp, right_name, 0);
if (table) {
v = __parser_get_vdbe(parser);
fk = table->pFKey;
}
if (table && fk) {
int i = 0;
static vdbe_op_t index_list_preface[] = {
{ OP_ColumnName, 0, 0, "id"},
{ OP_ColumnName, 1, 0, "seq"},
{ OP_ColumnName, 2, 0, "table"},
{ OP_ColumnName, 3, 0, "from"},
{ OP_ColumnName, 4, 0, "to"},
};
__vdbe_add_op_list(v, ARRAY_SIZE(index_list_preface),
index_list_preface);
while(fk) {
int j;
for (j = 0; j < fk->nCol; j++) {
__vdbe_add_op(v, OP_Integer, i, 0);
__vdbe_add_op(v, OP_Integer, j, 0);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1, fk->zTo,
P3_STATIC);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1,
table->aCol[fk->aCol[j].iFrom].zName,
P3_STATIC);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1,
fk->aCol[j].zCol, P3_STATIC);
__vdbe_add_op(v, OP_Callback, 5, 0);
}
++i;
fk = fk->pNextFrom;
}
}
} else
/*
* PRAGMA database_list
*/
if (strcasecmp(left_name, "database_list") == 0) {
int i;
static vdbe_op_t index_list_preface[] = {
{ OP_ColumnName, 0, 0, "seq"},
{ OP_ColumnName, 1, 0, "name"},
{ OP_ColumnName, 2, 0, "file"},
};
__vdbe_add_op_list(v, ARRAY_SIZE(index_list_preface),
index_list_preface);
for (i = 0; i < dbp->nDb; i++) {
if (dbp->aDb[i].pBt == 0)
continue;
DBSQL_ASSERT(dbp->aDb[i].zName != 0);
__vdbe_add_op(v, OP_Integer, i, 0);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1, dbp->aDb[i].zName, P3_STATIC);
__vdbe_add_op(v, OP_String, 0, 0);
__vdbe_change_p3(v, -1,
__sm_get_database_name(dbp->aDb[i].pBt), P3_STATIC);
__vdbe_add_op(v, OP_Callback, 3, 0);
}
} else
#ifndef NDEBUG
/*
* PRAGMA parser_trace
*/
if (strcasecmp(left_name, "parser_trace") == 0) {
extern void __sql_parser_trace(FILE*, char *);
if (__get_boolean(right_name)) {
__sql_parser_trace(stdout, "parser: ");
} else {
__sql_parser_trace(0, 0);
}
}
#endif
else {}
__dbsql_free(dbp, left_name);
__dbsql_free(dbp, right_name);
}

File diff suppressed because it is too large Load diff

View file

@ -1,952 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __vdbe_delete_trigger_step --
* Delete a linked list of TriggerStep structures.
*
* PUBLIC: void __vdbe_delete_trigger_step __P((trigger_step_t *));
*/
void
__vdbe_delete_trigger_step(trigger_step_t* ts)
{
while(ts) {
trigger_step_t * tmp = ts;
ts = ts->pNext;
if (tmp->target.dyn)
__dbsql_free(NULL, (char *)tmp->target.z);
__expr_delete(tmp->pWhere);
__expr_list_delete(tmp->pExprList);
__select_delete(tmp->pSelect);
__id_list_delete(tmp->pIdList);
__dbsql_free(NULL, tmp);
}
}
/*
* __begin_trigger --
* This is called by the parser when it sees a CREATE TRIGGER statement
* up to the point of the BEGIN before the trigger actions. A trigger_t
* structure is generated based on the information available and stored
* in parser->pNewTrigger. After the trigger actions have been parsed,
* the __finish_trigger() function is called to complete the trigger
* construction process.
*
* PUBLIC: void __begin_trigger __P((parser_t *, token_t *, int, int,
* PUBLIC: id_list_t *, src_list_t *, int, expr_t *, int));
*
* parser The parse context of the CREATE TRIGGER
* statement
* trigger The trigger of the trigger
* tr_tm One of TK_BEFORE, TK_AFTER, TK_INSTEAD
* op One of TK_INSERT, TK_UPDATE, TK_DELETE
* columns Column list if this is an UPDATE OF trigger
* tab_name The table name of the table/view for this
* trigger
* foreach One of TK_ROW or TK_STATEMENT
* when_clause WHEN clause
* temp_p True if the TEMPORARY keyword is present
*/
void
__begin_trigger(parser, trigger, tr_tm, op, columns, tab_name, foreach,
when_clause, temp_p)
parser_t *parser;
token_t *trigger;
int tr_tm;
int op;
id_list_t *columns;
src_list_t *tab_name;
int foreach;
expr_t *when_clause;
int temp_p;
{
trigger_t *nt;
table_t *table;
ref_normalizer_ctx_t normctx;
DBSQL *dbp = parser->db;
char *name = 0; /* Name of the trigger */
int db_idx; /* When database to store the trigger in */
/*
* Check that:
* 1. The trigger name does not already exist.
* 2. The table (or view) does exist in the same database as the
* trigger.
* 3. That we are not trying to create a trigger on either the
* master or master temp tables.
* 4. That we are not trying to create an INSTEAD OF trigger on a
* table.
* 5. That we are not trying to create a BEFORE or AFTER trigger on
* a view.
*/
if (parser->rc == ENOMEM)
goto trigger_cleanup;
DBSQL_ASSERT(tab_name->nSrc == 1);
if (parser->initFlag &&
__ref_normalizer_ctx_init(&normctx, parser, parser->iDb,
"trigger", trigger) &&
__ref_normalize_src_list(&normctx, tab_name)) {
goto trigger_cleanup;
}
table = __src_list_lookup(parser, tab_name);
if (!table) {
goto trigger_cleanup;
}
db_idx = (temp_p ? 1 : table->iDb);
if (db_idx >= 2 && !parser->initFlag) {
__error_msg(parser, "triggers may not be added to auxiliary "
"database %s", dbp->aDb[table->iDb].zName);
goto trigger_cleanup;
}
__dbsql_strndup(dbp, trigger->z, &name, trigger->n);
__str_unquote(name);
if( __hash_find(&(dbp->aDb[db_idx].trigHash), name,trigger->n+1) ){
__error_msg(parser, "trigger %T already exists", trigger);
goto trigger_cleanup;
}
if (strncasecmp(table->zName, MASTER_NAME,
strlen(MASTER_NAME)) == 0) {
__error_msg(parser, "cannot create trigger on system table");
parser->nErr++;
goto trigger_cleanup;
}
if (strncasecmp(table->zName, TEMP_MASTER_NAME,
strlen(TEMP_MASTER_NAME)) == 0) {
__error_msg(parser, "cannot create trigger on system table");
parser->nErr++;
goto trigger_cleanup;
}
if (table->pSelect && tr_tm != TK_INSTEAD) {
__error_msg(parser, "cannot create %s trigger on view: %S",
((tr_tm == TK_BEFORE) ? "BEFORE" : "AFTER"),
tab_name, 0);
goto trigger_cleanup;
}
if (!table->pSelect && tr_tm == TK_INSTEAD) {
__error_msg(parser, "cannot create INSTEAD OF"
" trigger on table: %S", tab_name, 0);
goto trigger_cleanup;
}
#ifndef DBSQL_NO_AUTH
{
int code = DBSQL_CREATE_TRIGGER;
const char *db = dbp->aDb[table->iDb].zName;
const char *db_trig = temp_p ? dbp->aDb[1].zName : db;
if (table->iDb == 1 || temp_p)
code = DBSQL_CREATE_TEMP_TRIGGER;
if (__auth_check(parser, code, name, table->zName, db_trig)) {
goto trigger_cleanup;
}
if (__auth_check(parser, DBSQL_INSERT,
SCHEMA_TABLE(table->iDb), 0, db)) {
goto trigger_cleanup;
}
}
#endif
/*
* INSTEAD OF triggers can only appear on views and BEGIN triggers
* cannot appear on views. So we might as well translate every
* INSTEAD OF trigger into a BEFORE trigger. It simplifies code
* elsewhere.
*/
if (tr_tm == TK_INSTEAD) {
tr_tm = TK_BEFORE;
}
/*
* Build the Trigger object.
*/
__dbsql_calloc(dbp, 1, sizeof(trigger_t), &nt);
if (nt == 0)
goto trigger_cleanup;
nt->name = name;
name = 0;
if (__dbsql_strdup(dbp, tab_name->a[0].zName, &nt->table) == ENOMEM)
goto trigger_cleanup;
nt->iDb = db_idx;
nt->iTabDb = table->iDb;
nt->op = op;
nt->tr_tm = tr_tm;
nt->pWhen = __expr_dup(when_clause);
nt->pColumns = __id_list_dup(columns);
nt->foreach = foreach;
__token_copy(&nt->nameToken,trigger);
DBSQL_ASSERT( parser->pNewTrigger==0 );
parser->pNewTrigger = nt;
trigger_cleanup:
__dbsql_free(dbp, name);
__src_list_delete(tab_name);
__id_list_delete(columns);
__expr_delete(when_clause);
}
/*
* __finish_trigger --
* This routine is called after all of the trigger actions have been
* parsed in order to complete the process of building the trigger.
*
* PUBLIC: void __finish_trigger __P((parser_t *, trigger_step_t *,
* PUBLIC: token_t *));
*
* parser The parse context of the CREATE TRIGGER
* statement
* steplist The triggered program
* all Token that describes the complete
* CREATE TRIGGER
*/
void
__finish_trigger(parser_t* parser, trigger_step_t* steplist, token_t* all)
{
ref_normalizer_ctx_t normctx;
trigger_t *nt = 0; /* The trigger whose construction is finishing up */
DBSQL *dbp = parser->db;
if (parser->nErr || parser->pNewTrigger == 0)
goto triggerfinish_cleanup;
nt = parser->pNewTrigger;
parser->pNewTrigger = 0;
nt->step_list = steplist;
while(steplist) {
steplist->pTrig = nt;
steplist = steplist->pNext;
}
if (__ref_normalizer_ctx_init(&normctx, parser, nt->iDb,
"trigger", &nt->nameToken) &&
__ref_normalize_trigger_step(&normctx, nt->step_list)) {
goto triggerfinish_cleanup;
}
/*
* if we are not initializing, and this trigger is not on a TEMP
* table, build the master entry.
*/
if (!parser->initFlag) {
static vdbe_op_t insert_trig[] = {
{ OP_NewRecno, 0, 0, 0 },
{ OP_String, 0, 0, "trigger" },
{ OP_String, 0, 0, 0 }, /* 2: trigger name */
{ OP_String, 0, 0, 0 }, /* 3: table name */
{ OP_Integer, 0, 0, 0 },
{ OP_String, 0, 0, 0 }, /* 5: SQL */
{ OP_MakeRecord, 5, 0, 0 },
{ OP_PutIntKey, 0, 0, 0 },
};
int addr;
vdbe_t *v;
/*
* Make an entry in the master table.
*/
v = __parser_get_vdbe(parser);
if (v == 0)
goto triggerfinish_cleanup;
__vdbe_prepare_write(parser, 0, 0);
__open_master_table(v, nt->iDb);
addr = __vdbe_add_op_list(v, ARRAY_SIZE(insert_trig),
insert_trig);
__vdbe_change_p3(v, (addr + 2), nt->name, 0);
__vdbe_change_p3(v, (addr + 3), nt->table, 0);
__vdbe_change_p3(v, (addr + 5), all->z, all->n);
if (nt->iDb == 0) {
__change_schema_signature(dbp, v);
}
__vdbe_add_op(v, OP_Close, 0, 0);
__vdbe_conclude_write(parser);
}
if (!parser->explain) {
table_t *table;
__hash_insert(&dbp->aDb[nt->iDb].trigHash,
nt->name, (strlen(nt->name) + 1), nt);
table = __locate_table(parser, nt->table,
dbp->aDb[nt->iTabDb].zName);
DBSQL_ASSERT(table != 0);
nt->pNext = table->pTrigger;
table->pTrigger = nt;
nt = 0;
}
triggerfinish_cleanup:
__vdbe_delete_trigger(nt);
__vdbe_delete_trigger(parser->pNewTrigger);
parser->pNewTrigger = 0;
__vdbe_delete_trigger_step(steplist);
}
/*
* __persist_trigger_step --
* Make a copy of all components of the given trigger step. This has
* the effect of copying all expr_t.token.z values into memory obtained
* from __dbsql_calloc(). As initially created, the expr_t.token.z values
* all point to the input string that was fed to the parser. But that
* string is ephemeral - it will go away as soon as the dbsql_exec()
* call that started the parser exits. This routine makes a persistent
* copy of all the Expr.token.z strings so that the trigger_step_t
* structure will be valid even after the dbsql_exec() call returns.
*
* STATIC: static void __persist_trigger_step __P((trigger_step_t *));
*/
static void
__persist_trigger_step(trigger_step_t* ts)
{
if (ts->target.z) {
__dbsql_strndup(NULL, ts->target.z, &ts->target.z, ts->target.n);
ts->target.dyn = 1;
}
if (ts->pSelect) {
select_t *new = __select_dup(ts->pSelect);
__select_delete(ts->pSelect);
ts->pSelect = new;
}
if( ts->pWhere ){
expr_t *new = __expr_dup(ts->pWhere);
__expr_delete(ts->pWhere);
ts->pWhere = new;
}
if (ts->pExprList) {
expr_list_t *new = __expr_list_dup(ts->pExprList);
__expr_list_delete(ts->pExprList);
ts->pExprList = new;
}
if (ts->pIdList) {
id_list_t *new = __id_list_dup(ts->pIdList);
__id_list_delete(ts->pIdList);
ts->pIdList = new;
}
}
/*
* __trigger_select_step --
* Turn a SELECT statement (that the 'select' parameter points to) into
* a trigger step. Return a pointer to a trigger_step_t structure.
*
* The parser calls this routine when it finds a SELECT statement in
* body of a TRIGGER.
*
* PUBLIC: trigger_step_t * __trigger_select_step __P((select_t *));
*/
trigger_step_t *
__trigger_select_step(select_t* select)
{
trigger_step_t *ts;
if (__dbsql_calloc(NULL, 1, sizeof(trigger_step_t), &ts) == ENOMEM)
return 0;
ts->op = TK_SELECT;
ts->pSelect = select;
ts->orconf = OE_Default;
__persist_trigger_step(ts);
return ts;
}
/*
* __trigger_insert_step --
* Build a trigger step out of an INSERT statement. Return a pointer
* to the new trigger step.
*
* The parser calls this routine when it sees an INSERT inside the
* body of a trigger.
*
* PUBLIC: trigger_step_t *__trigger_insert_step __P((token_t *, id_list_t *,
* PUBLIC: expr_list_t *, select_t *, int));
*
* tab_name Name of the table into which we insert
* column List of columns in tab_name to insert into
* elist The VALUE clause: a list of values to be
* inserted
* select A SELECT statement that supplies values
* orconf The conflict algorithm (OE_Abort, OE_Replace,
* etc.)
*/
trigger_step_t *
__trigger_insert_step(token_t* tab_name, id_list_t* column, expr_list_t* elist, select_t* select, int orconf)
{
trigger_step_t *ts;
if (__dbsql_calloc(NULL, 1, sizeof(trigger_step_t), &ts) == ENOMEM)
return 0;
DBSQL_ASSERT(elist == 0 || select == 0);
DBSQL_ASSERT(elist != 0 || select != 0);
ts->op = TK_INSERT;
ts->pSelect = select;
ts->target = *tab_name;
ts->pIdList = column;
ts->pExprList = elist;
ts->orconf = orconf;
__persist_trigger_step(ts);
return ts;
}
/*
* __trigger_update_step --
* Construct a trigger step that implements an UPDATE statement and return
* a pointer to that trigger step. The parser calls this routine when it
* sees an UPDATE statement inside the body of a CREATE TRIGGER.
*
* PUBLIC: trigger_step_t *__trigger_update_step __P((token_t *, expr_list_t *,
* PUBLIC: expr_t *, int));
*
* tab_name Name of the table to be updated
* elist The SET clause: list of column and new values
* where_clause The WHERE clause
* orconf The conflict algorithm. (OE_Abort, OE_Ignore,
* etc)
*/
trigger_step_t *
__trigger_update_step(token_t* tab_name, expr_list_t* elist, expr_t* where_clause, int orconf)
{
trigger_step_t *ts;
if (__dbsql_calloc(NULL, 1, sizeof(trigger_step_t), &ts) == ENOMEM)
return 0;
ts->op = TK_UPDATE;
ts->target = *tab_name;
ts->pExprList = elist;
ts->pWhere = where_clause;
ts->orconf = orconf;
__persist_trigger_step(ts);
return ts;
}
/*
* __trigger_delete_step --
* Construct a trigger step that implements a DELETE statement and return
* a pointer to that trigger step. The parser calls this routine when it
* sees a DELETE statement inside the body of a CREATE TRIGGER.
*
* PUBLIC: trigger_step_t *__trigger_delete_step __P((token_t *, expr_t *));
*/
trigger_step_t *
__trigger_delete_step(token_t* tab_name, expr_t* where_clause)
{
trigger_step_t *ts;
if (__dbsql_calloc(NULL, 1, sizeof(trigger_step_t), &ts) == ENOMEM)
return 0;
ts->op = TK_DELETE;
ts->target = *tab_name;
ts->pWhere = where_clause;
ts->orconf = OE_Default;
__persist_trigger_step(ts);
return ts;
}
/*
* __vdbe_delete_trigger --
* Recursively delete a trigger_t structure
*
* PUBLIC: void __vdbe_delete_trigger __P((trigger_t *));
*/
void
__vdbe_delete_trigger(trigger_t* trigger)
{
if (trigger == 0)
return;
__vdbe_delete_trigger_step(trigger->step_list);
__dbsql_free(NULL, trigger->name);
__dbsql_free(NULL, trigger->table);
__expr_delete(trigger->pWhen);
__id_list_delete(trigger->pColumns);
if (trigger->nameToken.dyn)
__dbsql_free(NULL, (char*)trigger->nameToken.z);
__dbsql_free(NULL, trigger);
}
/*
* __drop_trigger --
* This function is called to drop a trigger from the database schema.
*
* This may be called directly from the parser and therefore identifies
* the trigger by name. The __drop_trigger_ptr() routine does the
* same job as this routine except it take a spointer to the trigger
* instead of the trigger name.
*
* Note that this function does not delete the trigger entirely. Instead
* it removes it from the internal schema and places it in the trigDrop
* hash table. This is so that the trigger can be restored into the
* database schema if the transaction is rolled back.
*
* PUBLIC: void __drop_trigger __P((parser_t *, src_list_t *));
*/
void
__drop_trigger(parser_t* parser, src_list_t* trig_list)
{
int i;
trigger_t *trigger;
const char *db_name;
const char *trig_name;
int name_len;
DBSQL *dbp = parser->db;
if (parser->rc == ENOMEM)
goto err;
DBSQL_ASSERT(trig_list->nSrc == 1);
db_name = trig_list->a[0].zDatabase;
trig_name = trig_list->a[0].zName;
name_len = strlen(trig_name);
for (i = 0; i < dbp->nDb; i++) {
int j = (i < 2) ? (i ^ 1) : i; /* Search TEMP before MAIN. */
if (db_name &&
strcasecmp(dbp->aDb[j].zName, db_name))
continue;
trigger = __hash_find(&(dbp->aDb[j].trigHash), trig_name,
(name_len + 1));
if (trigger)
break;
}
if (!trigger) {
__error_msg(parser, "no such trigger: %S", trig_list, 0);
goto err;
}
__drop_trigger_ptr(parser, trigger, 0);
err:
__src_list_delete(trig_list);
}
/*
* __drop_trigger_ptr --
* Drop a trigger given a pointer to that trigger. If nested is false,
* then also generate code to remove the trigger from the DBSQL_MASTER
* table.
*
* PUBLIC: void __drop_trigger_ptr __P((parser_t *, trigger_t *, int));
*/
void
__drop_trigger_ptr(parser_t* parser, trigger_t* trigger, int nested)
{
table_t *table;
vdbe_t *v;
DBSQL *dbp = parser->db;
DBSQL_ASSERT(trigger->iDb < dbp->nDb);
if (trigger->iDb >= 2) {
__error_msg(parser, "triggers may not be removed from "
"auxiliary database %s",
dbp->aDb[trigger->iDb].zName);
return;
}
table = __find_table(dbp, trigger->table,
dbp->aDb[trigger->iTabDb].zName);
DBSQL_ASSERT(table);
DBSQL_ASSERT(table->iDb == trigger->iDb || trigger->iDb == 1);
#ifndef DBSQL_NO_AUTH
{
int code = DBSQL_DROP_TRIGGER;
const char *db = dbp->aDb[trigger->iDb].zName;
const char *tab = SCHEMA_TABLE(trigger->iDb);
if (trigger->iDb)
code = DBSQL_DROP_TEMP_TRIGGER;
if (__auth_check(parser, code, trigger->name,
table->zName, db) ||
__auth_check(parser, DBSQL_DELETE, tab, 0, db)) {
return;
}
}
#endif
/*
* Generate code to destroy the database record of the trigger.
*/
if (table != 0 && !nested && (v = __parser_get_vdbe(parser)) != 0) {
int base;
static vdbe_op_t drop_trigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String, 0, 0, 0}, /* 1 */
{ OP_Column, 0, 1, 0},
{ OP_Ne, 0, ADDR(8), 0},
{ OP_String, 0, 0, "trigger"},
{ OP_Column, 0, 0, 0},
{ OP_Ne, 0, ADDR(8), 0},
{ OP_Delete, 0, 0, 0},
{ OP_Next, 0, ADDR(1), 0}, /* 8 */
};
__vdbe_prepare_write(parser, 0, 0);
__open_master_table(v, trigger->iDb);
base = __vdbe_add_op_list(v, ARRAY_SIZE(drop_trigger),
drop_trigger);
__vdbe_change_p3(v, base+1, trigger->name, 0);
if (trigger->iDb == 0) {
__change_schema_signature(dbp, v);
}
__vdbe_add_op(v, OP_Close, 0, 0);
__vdbe_conclude_write(parser);
}
/*
* If this is not an "explain", then delete the trigger structure.
*/
if (!parser->explain) {
const char *name = trigger->name;
int len = strlen(name);
if (table->pTrigger == trigger) {
table->pTrigger = trigger->pNext;
} else {
trigger_t *cc = table->pTrigger;
while(cc) {
if (cc->pNext == trigger) {
cc->pNext = cc->pNext->pNext;
break;
}
cc = cc->pNext;
}
DBSQL_ASSERT(cc);
}
__hash_insert(&(dbp->aDb[trigger->iDb].trigHash), name,
(len + 1), 0);
__vdbe_delete_trigger(trigger);
}
}
/*
* __check_column_overlap --
* 'elist' is the SET clause of an UPDATE statement. Each entry
* in 'elist' is of the format <id>=<expr>. If any of the entries
* in 'elist' have an <id> which matches an identifier in 'id_list',
* then return TRUE. If 'id_list'==NULL, then it is considered a
* wildcard that matches anything. Likewise if elist==NULL then
* it matches anything so always return true. Return false only
* if there is no match.
*
* STATIC: static int __check_column_overlap __P((id_list_t *, expr_list_t *));
*/
static int
__check_column_overlap(id_list_t* id_list, expr_list_t* elist)
{
int e;
if (!id_list || !elist)
return 1;
for (e = 0; e < elist->nExpr; e++) {
if (__id_list_index(id_list, elist->a[e].zName) >= 0)
return 1;
}
return 0;
}
/*
* A global variable that is TRUE if we should always set up temp tables for
* for triggers, even if there are no triggers to code. This is used to test
* how much overhead the triggers algorithm is causing.
*
* This flag can be set or cleared using the "trigger_overhead_test" pragma.
* The pragma is not documented since it is not really part of the public
* interface, just the test procedure.
*/
int always_code_trigger_setup = 0; /* TODO, remove this global, place it
in the environment. */
/*
* __triggers_exist --
* Returns true if a trigger matching op, tr_tm and foreach that is NOT
* already on the parser_t objects trigger-stack (to prevent recursive
* trigger firing) is found in the list specified as trigger.
*
* PUBLIC: int __triggers_exist __P((parser_t *, trigger_t *, int, int, int,
* PUBLIC: expr_list_t *));
*
* parser Used to check for recursive triggers
* trigger A list of triggers associated with a table
* op One of TK_DELETE, TK_INSERT, TK_UPDATE
* tr_tm One of TK_BEFORE, TK_AFTER
* foreach One of TK_ROW or TK_STATEMENT
* changes Columns that change in an UPDATE statement
*/
int __triggers_exist(parser, trigger, op, tr_tm, foreach, changes)
parser_t *parser;
trigger_t *trigger;
int op;
int tr_tm;
int foreach;
expr_list_t *changes;
{
trigger_t * trig_cursor;
if (always_code_trigger_setup) {
return 1;
}
trig_cursor = trigger;
while (trig_cursor) {
if (trig_cursor->op == op &&
trig_cursor->tr_tm == tr_tm &&
trig_cursor->foreach == foreach &&
__check_column_overlap(trig_cursor->pColumns, changes)) {
trigger_stack_t *ss;
ss = parser->trigStack;
while (ss && ss->pTrigger != trigger) {
ss = ss->pNext;
}
if (!ss)
return 1;
}
trig_cursor = trig_cursor->pNext;
}
return 0;
}
/*
* __target_src_list --
* Convert the pStep->target token into a src_list_t and return a pointer
* to that src_list_t.
*
* This routine adds a specific database name, if needed, to the target
* when forming the src_list_t. This prevents a trigger in one database
* from referring to a target in another database. An exception is when
* the trigger is in TEMP in which case it can refer to any other database
* it wants.
*
* STATIC: static src_list_t *__target_src_list __P((parser_t *,
* STATIC: trigger_step_t *));
*
* parser The parsing context
* step The trigger containing the target token
*/
static src_list_t *targetSrcList(parser, step)
parser_t *parser;
trigger_step_t *step;
{
token_t db; /* Dummy database name token */
int db_idx; /* Index of the database to use */
src_list_t *src; /* SrcList to be returned */
db_idx = step->pTrig->iDb;
if (db_idx == 0 || db_idx >= 2) {
DBSQL_ASSERT(db_idx < parser->db->nDb);
db.z = parser->db->aDb[db_idx].zName;
db.n = strlen(db.z);
src = __src_list_append(0, &db, &step->target);
} else {
src = __src_list_append(0, &step->target, 0);
}
return src;
}
/*
* __code_trigger_prigram --
* Generate VDBE code for zero or more statements inside the body of a
* trigger.
*
* STATIC: static int __code_trigger_prigram __P(());
*
* parser The parser context
* steplist List of statements inside the trigger body
* orconfin Conflict algorithm. (OE_Abort, etc)
*/
static int
__code_trigger_program(parser_t* parser, trigger_step_t* steplist, int orconfin)
{
int orconf;
trigger_step_t * ts = steplist;
while (ts) {
int saveNTab = parser->nTab;
orconf = (orconfin == OE_Default)?ts->orconf:orconfin;
parser->trigStack->orconf = orconf;
switch(ts->op) {
case TK_SELECT: {
select_t * ss = __select_dup(ts->pSelect);
DBSQL_ASSERT(ss);
DBSQL_ASSERT(ss->pSrc);
__select(parser, ss, SRT_Discard, 0, 0, 0, 0);
__select_delete(ss);
break;
}
case TK_UPDATE: {
src_list_t *src;
src = targetSrcList(parser, ts);
__vdbe_add_op(parser->pVdbe, OP_ListPush, 0, 0);
__update(parser, src,
__expr_list_dup(ts->pExprList),
__expr_dup(ts->pWhere), orconf);
__vdbe_add_op(parser->pVdbe, OP_ListPop, 0, 0);
break;
}
case TK_INSERT: {
src_list_t *src;
src = targetSrcList(parser, ts);
__insert(parser, src,
__expr_list_dup(ts->pExprList),
__select_dup(ts->pSelect),
__id_list_dup(ts->pIdList), orconf);
break;
}
case TK_DELETE: {
src_list_t *src;
__vdbe_add_op(parser->pVdbe, OP_ListPush, 0, 0);
src = targetSrcList(parser, ts);
__delete_from(parser, src, __expr_dup(ts->pWhere));
__vdbe_add_op(parser->pVdbe, OP_ListPop, 0, 0);
break;
}
default:
DBSQL_ASSERT(0);
}
parser->nTab = saveNTab;
ts = ts->pNext;
}
return 0;
}
/*
* __code_row_trigger --
* This is called to code FOR EACH ROW triggers.
*
* When the code that this function generates is executed, the following
* must be true:
*
* 1. No cursors may be open in the main database. (But newIdx and oldIdx
* can be indices of cursors in temporary tables. See below.)
*
* 2. If the triggers being coded are ON INSERT or ON UPDATE triggers,
* then a temporary vdbe cursor (index newIdx) must be open and
* pointing at a row containing values to be substituted for new.*
* expressions in the trigger program(s).
*
* 3. If the triggers being coded are ON DELETE or ON UPDATE triggers,
* then a temporary vdbe cursor (index oldIdx) must be open and
* pointing at a row containing values to be substituted for old.*
* expressions in the trigger program(s).
*
* PUBLIC: int __code_row_trigger __P(());
*
* parser Parser context
* op One of TK_UPDATE, TK_INSERT, TK_DELETE
* changes Changes list for any UPDATE OF triggers
* tr_tm One of TK_BEFORE, TK_AFTER
* table The table to code triggers from
* new_idx The indice of the "new" row to access
* old_idx The indice of the "old" row to access
* orconf ON CONFLICT policy
* ignore_jump Instruction to jump to for RAISE(IGNORE)
*/
int __code_row_trigger(parser, op, changes, tr_tm, table, new_idx, old_idx,
orconf, ignore_jump)
parser_t *parser;
int op;
expr_list_t *changes;
int tr_tm;
table_t *table;
int new_idx;
int old_idx;
int orconf;
int ignore_jump;
{
trigger_t * trigger;
trigger_stack_t * trig_stack;
DBSQL *dbp = parser->db;
DBSQL_ASSERT(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
DBSQL_ASSERT(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
DBSQL_ASSERT(new_idx != -1 || old_idx != -1);
trigger = table->pTrigger;
while(trigger) {
int fire_this = 0;
/*
* Determine whether we should code this trigger.
*/
if (trigger->op == op && trigger->tr_tm == tr_tm &&
trigger->foreach == TK_ROW) {
fire_this = 1;
trig_stack = parser->trigStack;
while(trig_stack) {
if (trig_stack->pTrigger == trigger) {
fire_this = 0;
}
trig_stack = trig_stack->pNext;
}
if (op == TK_UPDATE && trigger->pColumns &&
!__check_column_overlap(trigger->pColumns,
changes)) {
fire_this = 0;
}
}
if (fire_this && __dbsql_calloc(dbp, 1,sizeof(trigger_stack_t),
&trig_stack) != ENOMEM) {
int end_trigger;
src_list_t dummy_tab_list;
expr_t * when_expr;
auth_context_t authctx;
dummy_tab_list.nSrc = 0;
/*
* Push an entry on to the trigger stack.
*/
trig_stack->pTrigger = trigger;
trig_stack->newIdx = new_idx;
trig_stack->oldIdx = old_idx;
trig_stack->pTab = table;
trig_stack->pNext = parser->trigStack;
trig_stack->ignoreJump = ignore_jump;
parser->trigStack = trig_stack;
__auth_context_push(parser, &authctx, trigger->name);
/*
* Code the WHEN clause.
*/
end_trigger = __vdbe_make_label(parser->pVdbe);
when_expr = __expr_dup(trigger->pWhen);
if (__expr_resolve_ids(parser, &dummy_tab_list, 0,
when_expr)) {
parser->trigStack = parser->trigStack->pNext;
__dbsql_free(dbp, trig_stack);
__expr_delete(when_expr);
return 1;
}
__expr_if_false(parser, when_expr, end_trigger, 1);
__expr_delete(when_expr);
__code_trigger_program(parser, trigger->step_list,
orconf);
/*
* Pop the entry off the trigger stack.
*/
parser->trigStack = parser->trigStack->pNext;
__auth_context_pop(&authctx);
__dbsql_free(dbp, trig_stack);
__vdbe_resolve_label(parser->pVdbe, end_trigger);
}
trigger = trigger->pNext;
}
return 0;
}

View file

@ -1,527 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains routines that handle UPDATE statements.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __update --
* Process an UPDATE statement.
*
* UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
* \_______/ \________/ \______/ \________________/
* on_error tab_list changes where
*
* PUBLIC: void __update __P((parser_t *, src_list_t *, expr_list_t *,
* PUBLIC: expr_t *, int));
*
* parser The parser context
* tab_list The table in which we should change things
* changes Things to be changed
* where The WHERE clause. May be null
* on_error How to handle constraint errors
*/
void __update(parser, tab_list, changes, where, on_error)
parser_t *parser;
src_list_t *tab_list;
expr_list_t *changes;
expr_t *where;
int on_error;
{
int rc;
int i, j; /* Loop counters */
table_t *table; /* The table to be updated */
int addr; /* VDBE instruction address of the start of
the loop */
where_info_t *winfo; /* Information about the WHERE clause */
vdbe_t *v; /* The virtual database engine */
index_t *idx; /* For looping over indices */
int num_idx; /* Number of indices that need updating */
int total_num_idx; /* Total number of indices */
int cur; /* VDBE Cursor number of table */
DBSQL *dbp; /* The database structure */
index_t **indices = 0;/* An array of indices that need updating too */
char *idx_used = 0; /* idx_used[i]==1 if the i-th index is used */
int *xref = 0; /* xref[i] is the index in changes->a[] of the
an expression for the i-th column of the
table. xref[i]==-1 if the i-th column is not
changed. */
int recno_will_change_p;/* True if the record number is being changed*/
expr_t *recno; /* Expression defining the new record number */
int open_all_p; /* True if all indices need to be opened */
int is_view_p; /* Trying to update a view */
auth_context_t auth; /* The authorization context */
int before_triggers; /* True if there are any BEFORE triggers */
int after_triggers; /* True if there are any AFTER triggers */
int row_triggers_exist = 0;/* True if any row triggers exist */
int new_idx = -1;/* index of trigger "new" temp table */
int old_idx = -1;/* index of trigger "old" temp table */
select_t *view;
auth.pParse = 0;
if (parser->nErr || parser->rc == ENOMEM)
goto update_cleanup;
dbp = parser->db;
DBSQL_ASSERT(tab_list->nSrc == 1);
/*
* Locate the table which we want to update.
*/
table = __src_list_lookup(parser, tab_list);
if (table == 0)
goto update_cleanup;
before_triggers = __triggers_exist(parser, table->pTrigger,
TK_UPDATE, TK_BEFORE, TK_ROW,
changes);
after_triggers = __triggers_exist(parser, table->pTrigger,
TK_UPDATE, TK_AFTER, TK_ROW,
changes);
row_triggers_exist = before_triggers || after_triggers;
is_view_p = (table->pSelect != 0);
if (__is_table_read_only(parser, table, before_triggers)) {
goto update_cleanup;
}
if (is_view_p) {
if (__view_get_column_names(parser, table)) {
goto update_cleanup;
}
}
if (__dbsql_calloc(dbp, table->nCol, sizeof(int), &xref) == ENOMEM)
goto update_cleanup;
for (i = 0; i < table->nCol; i++) {
xref[i] = -1;
}
/*
* If there are FOR EACH ROW triggers, allocate cursors for the
* special OLD and NEW tables.
*/
if (row_triggers_exist) {
new_idx = parser->nTab++;
old_idx = parser->nTab++;
}
/*
* Allocate a cursors for the main database table and for all indices.
* The index cursors might not be used, but if they are used they
* need to occur right after the database cursor. So go ahead and
* allocate enough space, just in case.
*/
tab_list->a[0].iCursor = cur = parser->nTab++;
for (idx = table->pIndex; idx; idx = idx->pNext) {
parser->nTab++;
}
/*
* Resolve the column names in all the expressions of the
* of the UPDATE statement. Also find the column index
* for each column to be updated in the changes array. For each
* column to be updated, make sure we have authorization to change
* that column.
*/
recno_will_change_p = 0;
for (i = 0; i < changes->nExpr; i++) {
if (__expr_resolve_ids(parser, tab_list, 0,
changes->a[i].pExpr)) {
goto update_cleanup;
}
if (__expr_check(parser, changes->a[i].pExpr, 0, 0)) {
goto update_cleanup;
}
for (j = 0; j < table->nCol; j++) {
if (strcasecmp(table->aCol[j].zName,
changes->a[i].zName) == 0) {
if (j == table->iPKey) {
recno_will_change_p = 1;
recno = changes->a[i].pExpr;
}
xref[j] = i;
break;
}
}
if (j >= table->nCol) {
if (__is_row_id(changes->a[i].zName)) {
recno_will_change_p = 1;
recno = changes->a[i].pExpr;
} else {
__error_msg(parser, "no such column: %s",
changes->a[i].zName);
goto update_cleanup;
}
}
#ifndef DBSQL_NO_AUTH
rc = __auth_check(parser, DBSQL_UPDATE, table->zName,
table->aCol[j].zName,
dbp->aDb[table->iDb].zName);
if (rc == DBSQL_DENY) {
goto update_cleanup;
} else if (rc == DBSQL_IGNORE) {
xref[j] = -1;
}
#endif
}
/*
* Allocate memory for the array indices[] and fill it with pointers
* to every index that needs to be updated. Indices only need
* updating if their key includes one of the columns named in changes
* or if the record number of the original table entry is changing.
*/
for (num_idx = total_num_idx = 0, idx = table->pIndex;
idx; idx = idx->pNext, total_num_idx++) {
if (recno_will_change_p) {
i = 0;
} else {
for (i = 0; i < idx->nColumn; i++) {
if (xref[idx->aiColumn[i]] >= 0)
break;
}
}
if (i < idx->nColumn)
num_idx++;
}
if (total_num_idx > 0) { /* TODO, is this the right amt to alloc? */
if (__dbsql_calloc(dbp, num_idx + total_num_idx,
sizeof(index_t *), &indices) == ENOMEM)
goto update_cleanup;
idx_used = (char*)&indices[num_idx];
}
for (num_idx = j = 0, idx = table->pIndex; idx; idx = idx->pNext, j++){
if (recno_will_change_p) {
i = 0;
} else {
for (i = 0; i < idx->nColumn; i++) {
if (xref[idx->aiColumn[i]] >= 0)
break;
}
}
if (i < idx->nColumn) {
indices[num_idx++] = idx;
idx_used[j] = 1;
} else {
idx_used[j] = 0;
}
}
/*
* Resolve the column names in all the expressions in the
* WHERE clause.
*/
if (where) {
if (__expr_resolve_ids(parser, tab_list, 0, where)) {
goto update_cleanup;
}
if (__expr_check(parser, where, 0, 0)) {
goto update_cleanup;
}
}
/*
* Start the view context.
*/
if (is_view_p) {
__auth_context_push(parser, &auth, table->zName);
}
/*
* Begin generating code.
*/
v = __parser_get_vdbe(parser);
if (v == 0)
goto update_cleanup;
__vdbe_prepare_write(parser, 1, table->iDb);
/*
* If we are trying to update a view, construct that view into
* a temporary table.
*/
if (is_view_p) {
view = __select_dup(table->pSelect);
__select(parser, view, SRT_TempTable, cur, 0, 0, 0);
__select_delete(view);
}
/*
* Begin the database scan.
*/
winfo = __where_begin(parser, tab_list, where, 1, 0);
if (winfo == 0)
goto update_cleanup;
/*
* Remember the index of every item to be updated.
*/
__vdbe_add_op(v, OP_ListWrite, 0, 0);
/*
* End the database scan loop.
*/
__where_end(winfo);
/*
* Initialize the count of updated rows.
*/
if (dbp->flags & DBSQL_CountRows && !parser->trigStack) {
__vdbe_add_op(v, OP_Integer, 0, 0);
}
if (row_triggers_exist) {
/*
* Create pseudo-tables for NEW and OLD
*/
__vdbe_add_op(v, OP_OpenPseudo, old_idx, 0);
__vdbe_add_op(v, OP_OpenPseudo, new_idx, 0);
/*
* The top of the update loop for when there are triggers.
*/
__vdbe_add_op(v, OP_ListRewind, 0, 0);
addr = __vdbe_add_op(v, OP_ListRead, 0, 0);
__vdbe_add_op(v, OP_Dup, 0, 0);
/*
* Open a cursor and make it point to the record that is
* being updated.
*/
__vdbe_add_op(v, OP_Dup, 0, 0);
if(!is_view_p) {
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenRead, cur, table->tnum);
}
__vdbe_add_op(v, OP_MoveTo, cur, 0);
/*
* Generate the OLD table.
*/
__vdbe_add_op(v, OP_Recno, cur, 0);
__vdbe_add_op(v, OP_RowData, cur, 0);
__vdbe_add_op(v, OP_PutIntKey, old_idx, 0);
/*
* Generate the NEW table.
*/
if (recno_will_change_p) {
__expr_code(parser, recno);
} else {
__vdbe_add_op(v, OP_Recno, cur, 0);
}
for(i = 0; i < table->nCol; i++) {
if (i == table->iPKey) {
__vdbe_add_op(v, OP_String, 0, 0);
continue;
}
j = xref[i];
if (j < 0) {
__vdbe_add_op(v, OP_Column, cur, i);
}else{
__expr_code(parser, changes->a[j].pExpr);
}
}
__vdbe_add_op(v, OP_MakeRecord, table->nCol, 0);
__vdbe_add_op(v, OP_PutIntKey, new_idx, 0);
if (!is_view_p) {
__vdbe_add_op(v, OP_Close, cur, 0);
}
/*
* Fire the BEFORE and INSTEAD OF triggers.
*/
if (__code_row_trigger(parser, TK_UPDATE, changes,
TK_BEFORE, table, new_idx, old_idx,
on_error, addr)) {
goto update_cleanup;
}
}
if (!is_view_p) {
/*
* Open every index that needs updating. Note that if any
* index could potentially invoke a REPLACE conflict resolution
* action, then we need to open all indices because we might
* need to be deleting some records.
*/
__vdbe_add_op(v, OP_Integer, table->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, cur, table->tnum);
if (on_error == OE_Replace) {
open_all_p = 1;
} else {
open_all_p = 0;
for (idx = table->pIndex; idx; idx = idx->pNext) {
if (idx->onError == OE_Replace) {
open_all_p = 1;
break;
}
}
}
for(i = 0, idx = table->pIndex; idx; idx = idx->pNext, i++) {
if (open_all_p || idx_used[i]) {
__vdbe_add_op(v, OP_Integer, idx->iDb, 0);
__vdbe_add_op(v, OP_OpenWrite, (cur + i + 1),
idx->tnum);
DBSQL_ASSERT(parser->nTab > (cur + i + 1));
}
}
/*
* Loop over every record that needs updating. We have to load
* the old data for each record to be updated because some
* columns might not change and we will need to copy the old
* value. Also, the old data is needed to delete the old index
* entires. So make the cursor point at the old record.
*/
if (!row_triggers_exist) {
__vdbe_add_op(v, OP_ListRewind, 0, 0);
addr = __vdbe_add_op(v, OP_ListRead, 0, 0);
__vdbe_add_op(v, OP_Dup, 0, 0);
}
__vdbe_add_op(v, OP_NotExists, cur, addr);
/*
* If the record number will change, push the record number
* as it will be after the update. (The old record number is
* currently on top of the stack.)
*/
if (recno_will_change_p) {
__expr_code(parser, recno);
__vdbe_add_op(v, OP_MustBeInt, 0, 0);
}
/*
* Compute new data for this record.
*/
for (i = 0; i < table->nCol; i++) {
if (i == table->iPKey) {
__vdbe_add_op(v, OP_String, 0, 0);
continue;
}
j = xref[i];
if (j < 0) {
__vdbe_add_op(v, OP_Column, cur, i);
} else {
__expr_code(parser, changes->a[j].pExpr);
}
}
/*
* Do constraint checks.
*/
__generate_constraint_checks(parser, table, cur, idx_used,
recno_will_change_p, 1, on_error,
addr);
/*
* Delete the old indices for the current record.
*/
__generate_row_index_delete(dbp, v, table, cur, idx_used);
/*
* If changing the record number, delete the old record.
*/
if (recno_will_change_p) {
__vdbe_add_op(v, OP_Delete, cur, 0);
}
/*
* Create the new index entries and the new record.
*/
__complete_insertion(parser, table, cur, idx_used,
recno_will_change_p, 1, -1);
}
/*
* Increment the row counter.
*/
if (dbp->flags & DBSQL_CountRows && !parser->trigStack) {
__vdbe_add_op(v, OP_AddImm, 1, 0);
}
/*
* If there are triggers, close all the cursors after each iteration
* through the loop. The fire the after triggers.
*/
if (row_triggers_exist) {
if (!is_view_p) {
for(i = 0, idx = table->pIndex; idx;
idx = idx->pNext, i++) {
if (open_all_p || idx_used[i]) {
__vdbe_add_op(v, OP_Close,
(cur + i + 1), 0);
}
}
__vdbe_add_op(v, OP_Close, cur, 0);
parser->nTab = cur;
}
if (__code_row_trigger(parser, TK_UPDATE, changes,
TK_AFTER, table, new_idx, old_idx,
on_error, addr)) {
goto update_cleanup;
}
}
/*
* Repeat the above with the next record to be updated, until
* all record selected by the WHERE clause have been updated.
*/
__vdbe_add_op(v, OP_Goto, 0, addr);
__vdbe_change_p2(v, addr, __vdbe_current_addr(v));
__vdbe_add_op(v, OP_ListReset, 0, 0);
/*
* Close all tables if there were no FOR EACH ROW triggers.
*/
if (!row_triggers_exist) {
for (i = 0, idx = table->pIndex; idx; idx = idx->pNext, i++) {
if (open_all_p || idx_used[i]) {
__vdbe_add_op(v, OP_Close, (cur + i + 1), 0);
}
}
__vdbe_add_op(v, OP_Close, cur, 0);
parser->nTab = cur;
} else {
__vdbe_add_op(v, OP_Close, new_idx, 0);
__vdbe_add_op(v, OP_Close, old_idx, 0);
}
__vdbe_conclude_write(parser);
/*
* Return the number of rows that were changed.
*/
if (dbp->flags & DBSQL_CountRows && !parser->trigStack) {
__vdbe_add_op(v, OP_ColumnName, 0, 0);
__vdbe_change_p3(v, -1, "rows updated", P3_STATIC);
__vdbe_add_op(v, OP_Callback, 1, 0);
}
update_cleanup:
__auth_context_pop(&auth);
__dbsql_free(NULL, indices);
__dbsql_free(NULL, xref);
__src_list_delete(tab_list);
__expr_list_delete(changes);
__expr_delete(where);
return;
}

View file

@ -1,76 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* This file contains code used to implement the VACUUM command.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#if !defined(DBSQL_OMIT_VACUUM) || DBSQL_OMIT_VACUUM
/*
* __vacuum --
* The non-standard VACUUM command is used to clean up the database,
* collapse free space, etc. It is modelled after the VACUUM command
* in PostgreSQL.
*
* PUBLIC: void __vacuum __P((parser_t *, token_t *));
*/
void
__vacuum(parser_t* parser, token_t* tab_name)
{
vdbe_t *v = __parser_get_vdbe(parser);
__vdbe_add_op(v, OP_Vacuum, 0, 0);
return;
}
/*
* __execute_vacuum --
* This routine implements the OP_Vacuum opcode of the VDBE. It works
* by running through each database asking each to reclaim space.
*
* PUBLIC: int __execute_vacuum __P((char **, DBSQL *));
*/
int
__execute_vacuum(char* *err_msgs, DBSQL* dbp)
{
return DBSQL_SUCCESS; /* NOTE: When DB implements compaction (someday)
then this will be the place to invoke the
__sm_compact() function. For now, its
a no-op. */
}
#else
/*
* __execute_vacuum --
* A no-op.
*
* PUBLIC: int __execute_vacuum __P((char **, DBSQL *));
*/
int
__execute_vacuum(char* *err_msgs, DBSQL* dbp)
{
return DBSQL_SUCCESS;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,209 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "dbsql_int.h"
int __dbsql_getopt_reset; /* global reset for VxWorks. */
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#undef BADCH
#define BADCH (int)'?'
#undef BADARG
#define BADARG (int)':'
#undef EMSG
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*
* PUBLIC: #ifndef HAVE_GETOPT
* PUBLIC: int getopt __P((int, char * const *, const char *));
* PUBLIC: #endif
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static char *progname;
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
/*
* VxWorks needs to be able to repeatedly call getopt from multiple
* programs within its global name space.
*/
if (__dbsql_getopt_reset) {
__dbsql_getopt_reset = 0;
opterr = optind = 1;
optopt = optreset = 0;
optarg = NULL;
progname = NULL;
place = EMSG;
}
if (!progname) {
if ((progname = __os_rpath(*nargv)) == NULL)
progname = *nargv;
else
++progname;
}
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (EOF);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (EOF);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if (optopt == (int)'-')
return (EOF);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", progname, optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
progname, optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

View file

@ -1,124 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#endif
/*
* memcmp --
*
* PUBLIC: #ifndef HAVE_MEMCMP
* PUBLIC: int memcmp __P((const void *, const void *, size_t));
* PUBLIC: #endif
*/
#ifndef HAVE_MEMCMP
int
memcmp(s1, s2, n)
char *s1, *s2;
size_t n;
{
if (n != 0) {
unsigned char *p1 = (unsigned char *)s1,
*p2 = (unsigned char *)s2;
do {
if (*p1++ != *p2++)
return (*--p1 - *--p2);
} while (--n != 0);
}
return (0);
}
#endif

View file

@ -1,238 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stdio.h>
#endif
#include "dbsql_int.h"
#define SEED_SZ 256
/*
* __rng_seed --
* Produce a sutable seed for our random number generator. In
* this case that means using the current time. The seed is
* written to a char[SEED_SZ] buffer passed by the caller.
* Note that when testing its useful to generate the same pattern
* of random numbers. We accomplish that by initializing the contents
* of 'buf' to '\0' when CONFIG_TEST is defined. In this way, tests
* are repeatable.
*/
#ifndef HAVE_SRAND48_R
void
__rng_seed(char* buf)
{
u_int32_t pid;
double jt;
u_int32_t i;
memset(buf, 0, SEED_SZ);
#ifdef CONFIG_TEST
return;
#else
__os_id(NULL, &pid, NULL);
__os_jtime(&jt);
for (i = 0; i < SEED_SZ; i++) {
if (i % 2)
buf[i] = (char)(pid & 0xf);
else
buf[i] = (char)((u_int32_t)jt & 0xf);
}
return;
#endif
}
#endif
/*
* srand48_r --
* Seed the random number generator before use.
*
* PUBLIC: #ifndef HAVE_SRAND48_R
* PUBLIC: int srand48_r __P((struct drand48_data *));
* PUBLIC: #endif
*/
#ifndef HAVE_SRAND48_R
int
srand48_r(buffer)
struct drand48_data *buffer;
{
int i;
char k[SEED_SZ];
buffer->j = 0;
buffer->i = 0;
__rng_seed(k);
for(i = 0; i < 256; i++) {
buffer->s[i] = i;
}
for(i = 0; i < 256; i++) {
int t;
buffer->j = (buffer->j + buffer->s[i] + k[i]) & 0xff;
t = buffer->s[buffer->j];
buffer->s[buffer->j] = buffer->s[i];
buffer->s[i] = t;
}
buffer->init_p = 1;
}
#endif
/*
* lrand48_r --
* A re-entrant version of a random number generator. This
* random number generator is based on the RC4 algorithm.
*
* STATIC: #ifndef HAVE_LRAND48_R
* STATIC: int lrand48_r __P((struct drand48_data *, double *));
* STATIC: #endif
*/
#ifndef HAVE_LRAND48_R
static int
lrand48_r(buffer, result)
struct drand48_data *buffer;
double *result;
{
/* TODO: am I sure there isn't a race in here? */
int t;
buffer->i = (buffer->i + 1) & 0xff;
buffer->j = (buffer->j + buffer->s[buffer->i]) & 0xff;
t = buffer->s[buffer->i];
buffer->s[buffer->i] = buffer->s[buffer->j];
buffer->s[buffer->j] = t;
t = buffer->s[buffer->i] + buffer->s[buffer->j];
*result = buffer->s[t & 0xff];
return 0;
}
#endif
/*
* rand8_r --
*
* PUBLIC: int rand8_r __P((struct drand48_data *, u_int8_t *));
*/
int
rand8_r(buffer, result)
struct drand48_data *buffer;
u_int8_t *result;
{
long int i;
int rc = lrand48_r(buffer, &i);
*result = i & 0xf;
return 0;
}
/*
* rand32_r --
*
* PUBLIC: int rand32_r __P((struct drand48_data *, u_int32_t *));
*/
int
rand32_r(buffer, result)
struct drand48_data *buffer;
u_int32_t *result;
{
int rc, i;
long int r, s;
rc = lrand48_r(buffer, &r);
for(i = 1; i < 4; i++) {
rc = lrand48_r(buffer, &s);
r = (r << 8) + s;
}
*result = r;
return rc;
}

View file

@ -1,157 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stdio.h>
#endif
#include "dbsql_int.h"
/*
* snprintf --
* Bounded version of sprintf.
*
* PUBLIC: #ifndef HAVE_SNPRINTF
* PUBLIC: int snprintf __P((char *, size_t, const char *, ...));
* PUBLIC: #endif
*/
#ifndef HAVE_SNPRINTF
int
#ifdef STDC_HEADERS
snprintf(char *str, size_t n, const char *fmt, ...)
#else
snprintf(str, n, fmt, va_alist)
char *str;
size_t n;
const char *fmt;
va_dcl
#endif
{
static int ret_charpnt = -1;
va_list ap;
int len;
COMPQUIET(n, 0);
/*
* Some old versions of sprintf return a pointer to the first argument
* instead of a character count. Assume the return value of snprintf,
* vsprintf, etc. will be the same as sprintf, and check the easy one.
*
* We do this test at run-time because it's not a test we can do in a
* cross-compilation environment.
*/
if (ret_charpnt == -1) {
char buf[10];
ret_charpnt =
(int)sprintf(buf, "123") != 3 ||
(int)sprintf(buf, "123456789") != 9 ||
(int)sprintf(buf, "1234") != 4;
}
#ifdef STDC_HEADERS
va_start(ap, fmt);
#else
va_start(ap);
#endif
len = vsprintf(str, fmt, ap);
va_end(ap);
return (ret_charpnt ? (int)strlen(str) : len);
}
#endif

View file

@ -1,151 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <string.h>
#endif
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
static const unsigned char charmap[] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
};
/*
* strcasecmp --
* Do strcmp(3) in a case-insensitive manner.
*
* PUBLIC: #ifndef HAVE_STRCASECMP
* PUBLIC: int strcasecmp __P((const char *, const char *));
* PUBLIC: #endif
*/
#ifndef HAVE_STRCASECMP
int
strcasecmp(s1, s2)
const char *s1, *s2;
{
register const unsigned char *cm = charmap,
*us1 = (const unsigned char *)s1,
*us2 = (const unsigned char *)s2;
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
return (0);
return (cm[*us1] - cm[*--us2]);
}
#endif
/*
* strncasecmp --
* Do strncmp(3) in a case-insensitive manner.
*
* PUBLIC: #ifndef HAVE_STRNCASECMP
* PUBLIC: int strncasecmp __P((const char *, const char *, size_t));
* PUBLIC: #endif
*/
#ifndef HAVE_STRNCASECMP
int
strncasecmp(s1, s2, n)
const char *s1, *s2;
register size_t n;
{
if (n != 0) {
register const unsigned char *cm = charmap,
*us1 = (const unsigned char *)s1,
*us2 = (const unsigned char *)s2;
do {
if (cm[*us1] != cm[*us2++])
return (cm[*us1] - cm[*--us2]);
if (*us1++ == '\0')
break;
} while (--n != 0);
}
return (0);
}
#endif

View file

@ -1,108 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#endif
/*
* strdup --
*
* PUBLIC: #ifndef HAVE_STRDUP
* PUBLIC: char *strdup __P((const char *));
* PUBLIC: #endif
*/
#ifndef HAVE_STRDUP
char *
strdup(str)
const char *str;
{
size_t len;
char *copy;
len = strlen(str) + 1;
if (!(copy = malloc((u_int)len)))
return (NULL);
memcpy(copy, str, len);
return (copy);
}
#endif
/*
* strndup --
*
* PUBLIC: #ifndef HAVE_STRNDUP
* PUBLIC: char *strndup __P((const char *, size_t));
* PUBLIC: #endif
*/
#ifndef HAVE_STRNDUP
char *
strndup(str, len)
const char *str;
size_t len;
{
char *copy;
if (len > strlen(str))
len = strlen(str);
if (!(copy = malloc((u_int)len + 1)))
return (NULL);
memcpy(copy, str, len + 1);
return (copy);
}
#endif

View file

@ -1,836 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* The following is an printf with some extra features (as well as some
* missing features). A few extensions to the formatting notation are
* supported:
* * The "=" flag (similar to "-") causes the output to be
* be centered in the appropriately sized field.
*
* * The %b field outputs an integer in binary notation.
*
* * The %c field now accepts a precision. The character output
* is repeated by the number of times the precision specifies.
*
* * The %' field works like %c, but takes as its character the
* next character of the format string, instead of the next
* argument. For example, printf("%.78'-") prints 78 minus
* signs, the same as printf("%.78c",'-').
*
* When compiled using GCC on a SPARC, this version of printf is
* faster than the library printf for SUN OS 4.1. Also, all functions
* are fully reentrant.
*
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* Conversion types fall into various categories as defined by the
* following enumeration.
*/
#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
#define etFLOAT 2 /* Floating point. %f */
#define etEXP 3 /* Exponentional notation. %e and %E */
#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g*/
#define etSIZE 5 /* Return number of characters processed so far. %n */
#define etSTRING 6 /* Strings. %s */
#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
#define etPERCENT 8 /* Percent symbol. %% */
#define etCHARX 9 /* Characters. %c */
#define etERROR 10 /* Used to indicate no such conversion type */
/* The rest are extensions, not normally found in printf() */
#define etCHARLIT 11 /* Literal characters. %' */
#define etSQLESCAPE 12 /* Strings with '\'' doubled. %q */
#define etSQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
NULL pointers replaced by SQL NULL. %Q */
/*
* Each builtin conversion character (ex: the 'd' in "%d") is described
* by an instance of the following structure
*/
typedef struct et_info {
char fmttype; /* The format field code letter */
u_int8_t base; /* The base for radix conversion */
u_int8_t flags; /* One or more of FLAG_ constants below */
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_INTERN 2 /* True if for internal use only */
u_int8_t type; /* Conversion paradigm */
char *charset; /* The character set for conversion */
char *prefix; /* Prefix on non-zero values in alt format */
} et_info_t;
/*
* The following table is searched linearly, so it is good to put the
* most frequently used conversion types first.
*/
static et_info_t fmtinfo[] = {
{ 'd', 10, 1, etRADIX, "0123456789", 0 },
{ 's', 0, 0, etSTRING, 0, 0 },
{ 'z', 0, 2, etDYNSTRING, 0, 0 },
{ 'q', 0, 0, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 0, etSQLESCAPE2, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, "01234567", "0" },
{ 'u', 10, 0, etRADIX, "0123456789", 0 },
{ 'x', 16, 0, etRADIX, "0123456789abcdef", "x0" },
{ 'X', 16, 0, etRADIX, "0123456789ABCDEF", "X0" },
{ 'f', 0, 1, etFLOAT, 0, 0 },
{ 'e', 0, 1, etEXP, "e", 0 },
{ 'E', 0, 1, etEXP, "E", 0 },
{ 'g', 0, 1, etGENERIC, "e", 0 },
{ 'G', 0, 1, etGENERIC, "E", 0 },
{ 'i', 10, 1, etRADIX, "0123456789", 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 10, 0, etRADIX, "0123456789", 0 },
};
#define etNINFO (sizeof(fmtinfo) / sizeof(fmtinfo[0]))
/*
* If NOFLOATINGPOINT is defined, then none of the floating point
* conversions will work.
*/
#ifndef etNOFLOATINGPOINT
/*
* et_get_digit --
* "*val" is a double such that 0.1 <= *val < 10.0
* Return the ascii code for the leading digit of *val, then
* multiply "*val" by 10.0 to renormalize.
*
* Example:
* input: *val = 3.14159
* output: *val = 1.4159 function return = '3'
*
* The counter *cnt is incremented each time. After counter exceeds
* 16 (the number of significant digits in a 64-bit float) '0' is
* always returned.
*/
static int
et_getdigit(long_double_t* val, int* cnt)
{
int digit;
long_double_t d;
if ((*cnt)++ >= 16 )
return '0';
digit = (int)*val;
d = digit;
digit += '0';
*val = (*val - d) * 10.0;
return digit;
}
#endif
#define etBUFSIZE 1024 /* Size of the output buffer */
/*
* __et_printf --
* The root printf-like program used by all variations implemented herein.
*
* INPUTS:
* func This is a pointer to a function taking three arguments
* 1. A pointer to anything. Same as the "arg" parameter.
* 2. A pointer to the list of characters to be output
* (Note, this list is NOT null terminated.)
* 3. An integer number of characters to be output.
* (Note: This number might be zero.)
*
* arg This is the pointer to anything which will be passed as the
* first argument to "func". Use it for whatever you like.
*
* fmt This is the format string, as in the usual print.
*
* ap This is a pointer to a list of arguments. Same as in
* vfprint.
*
* OUTPUTS:
* The return value is the total number of characters sent to
* the function "func". Returns -1 on a error.
*
* NOTE: The order in which automatic variables are declared below
* seems to make a big difference in determining how fast this function
* runs.
*/
static int
__et_printf(dbp, func, arg, fmt, ap)
DBSQL *dbp;
void (*func)(void*,char*,int);
void *arg;
const char *fmt;
va_list ap;
{
int c; /* Next character in the format string */
char *bufpt; /* Pointer to the conversion buffer */
int precision; /* Precision of the current field */
int length; /* Length of the field */
int idx; /* A general purpose loop counter */
int count; /* Total number of characters output */
int width; /* Width of the current field */
u_int8_t flag_leftjustify; /* True if "-" flag is present */
u_int8_t flag_plussign; /* True if "+" flag is present */
u_int8_t flag_blanksign; /* True if " " flag is present */
u_int8_t flag_alternateform; /* True if "#" flag is present */
u_int8_t flag_zeropad; /* True if field width constant starts
with zero */
u_int8_t flag_long; /* True if "l" flag is present */
unsigned long longvalue; /* Value for integer types */
long_double_t realvalue; /* Value for real types */
et_info_t *infop; /* Pointer to the appropriate info
structure */
char buf[etBUFSIZE]; /* Conversion buffer */
char prefix; /* Prefix character. "+" or "-" or " " or
'\0'. */
u_int8_t errorflag = 0; /* True if an error is encountered */
u_int8_t xtype; /* Conversion paradigm */
char *extra; /* Extra memory used for etTCLESCAPE
conversions */
static char spaces[] =
" "
" ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef etNOFLOATINGPOINT
int exp; /* exponent of real numbers */
double rounder; /* Used for rounding floating point values*/
u_int8_t flag_dp; /* True if decimal point should be shown */
u_int8_t flag_rtz; /* True if trailing zeros should be
removed */
u_int8_t flag_exp; /* True to force display of the exponent */
int nsd; /* Number of significant digits returned */
#endif
count = length = 0;
bufpt = 0;
for(; (c = (*fmt)) != 0; ++fmt) {
if (c != '%') {
int amt;
bufpt = (char *)fmt;
amt = 1;
while((c = (*++fmt)) != '%' && c != 0)
amt++;
(*func)(arg, bufpt, amt);
count += amt;
if (c == 0)
break;
}
if ((c = (*++fmt)) == 0) {
errorflag = 1;
(*func)(arg, "%", 1);
count++;
break;
}
/* Find out what flags are present. */
flag_leftjustify = flag_plussign = flag_blanksign =
flag_alternateform = flag_zeropad = 0;
do {
switch(c) {
case '-': flag_leftjustify = 1; c = 0; break;
case '+': flag_plussign = 1; c = 0; break;
case ' ': flag_blanksign = 1; c = 0; break;
case '#': flag_alternateform = 1; c = 0; break;
case '0': flag_zeropad = 1; c = 0; break;
default: break;
}
} while(c == 0 && (c = (*++fmt)) != 0);
/* Get the field width. */
width = 0;
if (c == '*') {
width = va_arg(ap, int);
if (width < 0) {
flag_leftjustify = 1;
width = -width;
}
c = *++fmt;
} else {
while(c >= '0' && c <= '9') {
width = (width * 10) + c - '0';
c = *++fmt;
}
}
if (width > etBUFSIZE - 10) {
width = etBUFSIZE - 10;
}
/* Get the precision. */
if (c == '.') {
precision = 0;
c = *++fmt;
if (c == '*') {
precision = va_arg(ap,int);
#ifndef etCOMPATIBILITY
/* This is sensible, but SUN OS 4.1 doesn't
do it. */
if (precision < 0)
precision = -precision;
#endif
c = *++fmt;
} else {
while(c >= '0' && c <= '9') {
precision = (precision * 10) + c - '0';
c = *++fmt;
}
}
/*
* Limit the precision to prevent overflowing buf[]
* during conversion
*/
if (precision > etBUFSIZE - 40)
precision = etBUFSIZE - 40;
} else {
precision = -1;
}
/* Get the conversion type modifier. */
if (c == 'l') {
flag_long = 1;
c = *++fmt;
} else {
flag_long = 0;
}
/* Fetch the info entry for the field. */
infop = 0;
xtype = etERROR;
for(idx = 0; idx < etNINFO; idx++) {
if (c == fmtinfo[idx].fmttype) {
infop = &fmtinfo[idx];
xtype = infop->type;
break;
}
}
extra = 0;
/*
* At this point, variables are initialized as follows:
*
* flag_alternateform TRUE if a '#' is present.
* flag_plussign TRUE if a '+' is present.
* flag_leftjustify TRUE if a '-' is present or
* if the field width was
* negative.
* flag_zeropad TRUE if the width began
* with 0.
* flag_long TRUE if the letter 'l' (ell)
* prefixed the conversion
* character.
* flag_blanksign TRUE if a ' ' is present.
* width The specified field width.
* This is always non-negative.
* Zero is the default.
* precision The specified precision. The
* default is -1.
* xtype The class of the conversion.
* infop Pointer to the appropriate
* info struct.
*/
switch(xtype) {
case etRADIX:
if (flag_long) {
longvalue = va_arg(ap, long);
} else{
longvalue = va_arg(ap, int);
}
#ifdef etCOMPATIBILITY
/*
* For the format %#x, the value zero is printed "0"
* not "0x0". I think this is stupid.
*/
if (longvalue == 0)
flag_alternateform = 0;
#else
/*
* More sensible: turn off the prefix for octal
* (to prevent "00"), but leave the prefix for hex.
*/
if (longvalue == 0 && infop->base == 8)
flag_alternateform = 0;
#endif
if (infop->flags & FLAG_SIGNED) {
if (*(long *)&longvalue < 0) {
longvalue = -*(long *)&longvalue;
prefix = '-';
} else if (flag_plussign) {
prefix = '+';
} else if (flag_blanksign) {
prefix = ' ';
} else {
prefix = 0;
}
} else {
prefix = 0;
}
if (flag_zeropad && precision < width - (prefix != 0)){
precision = width - (prefix != 0);
}
bufpt = &buf[etBUFSIZE];
{
register char *cset;
register int base;
cset = infop->charset;
base = infop->base;
do { /* Convert to ascii */
*(--bufpt) = cset[longvalue % base];
longvalue = longvalue / base;
} while(longvalue > 0);
}
length = &buf[etBUFSIZE] - bufpt;
for(idx = precision - length; idx > 0; idx--) {
*(--bufpt) = '0'; /* Zero pad */
}
if (prefix)
*(--bufpt) = prefix; /* Add sign */
if (flag_alternateform && infop->prefix) {
/* Add "0" or "0x" */
char *pre, x;
pre = infop->prefix;
if (*bufpt != pre[0]) {
for(pre = infop->prefix;
(x = (*pre)) != 0; pre++) {
*(--bufpt) = x;
}
}
}
length = &buf[etBUFSIZE] - bufpt;
break;
case etFLOAT:
case etEXP:
case etGENERIC:
realvalue = va_arg(ap, double);
#ifndef etNOFLOATINGPOINT
if (precision < 0)
precision = 6; /* Set default precision */
if (precision > etBUFSIZE - 10)
precision = etBUFSIZE - 10;
if (realvalue < 0.0) {
realvalue = -realvalue;
prefix = '-';
} else {
if (flag_plussign)
prefix = '+';
else if (flag_blanksign)
prefix = ' ';
else
prefix = 0;
}
if (infop->type == etGENERIC && precision > 0)
precision--;
rounder = 0.0;
#ifdef COMPATIBILITY
/*
* Rounding works like BSD when the constant 0.4999 is
* used. Wierd!
*/
for(idx = precision, rounder = 0.4999; idx > 0;
idx--, rounder *= 0.1);
#else
/*
* It makes more sense to use 0.5
*/
for(idx = precision, rounder = 0.5; idx > 0;
idx--, rounder *= 0.1);
#endif
if (infop->type == etFLOAT)
realvalue += rounder;
/*
* Normalize realvalue to within
* 10.0 > realvalue >= 1.0
*/
exp = 0;
if (realvalue > 0.0) {
int k = 0;
while(realvalue >= 1e8 && k++ < 100) {
realvalue *= 1e-8;
exp+=8;
}
while(realvalue >= 10.0 && k++ < 100) {
realvalue *= 0.1;
exp++;
}
while(realvalue < 1e-8 && k++ < 100) {
realvalue *= 1e8;
exp-=8;
}
while(realvalue < 1.0 && k++ < 100) {
realvalue *= 10.0;
exp--;
}
if (k >= 100) {
bufpt = "NaN";
length = 3;
break;
}
}
bufpt = buf;
/*
* If the field type is etGENERIC, then convert to
* either etEXP or etFLOAT, as appropriate.
*/
flag_exp = (xtype == etEXP);
if (xtype != etFLOAT) {
realvalue += rounder;
if (realvalue >= 10.0) {
realvalue *= 0.1;
exp++;
}
}
if (xtype == etGENERIC) {
flag_rtz = !flag_alternateform;
if (exp<-4 || exp > precision) {
xtype = etEXP;
} else {
precision = precision - exp;
xtype = etFLOAT;
}
} else {
flag_rtz = 0;
}
/*
* The "exp+precision" test causes output to be of
* type etEXP if the precision is too large to fit
* in buf[].
*/
nsd = 0;
if (xtype == etFLOAT &&
exp + precision < etBUFSIZE - 30) {
flag_dp =(precision > 0 || flag_alternateform);
if (prefix) {
*(bufpt++) = prefix; /* Sign */
}
if (exp < 0) {
*(bufpt++) = '0'; /* Digits before
"." */
} else {
for(; exp >= 0; exp--) {
*(bufpt++) =
et_getdigit(&realvalue,
&nsd);
}
}
if (flag_dp) {
*(bufpt++) = '.';/* The decimal point*/
}
for(exp++; exp < 0 && precision > 0;
precision--, exp++) {
*(bufpt++) = '0';
}
while((precision--) > 0) {
*(bufpt++) = et_getdigit(&realvalue,
&nsd);
}
*(bufpt--) = 0; /* Null terminate */
if (flag_rtz && flag_dp) {
/* Remove trailing zeros and "." */
while( bufpt >= buf && *bufpt == '0') {
*(bufpt--) = 0;
}
if (bufpt >= buf && *bufpt == '.' ) {
*(bufpt--) = 0;
}
}
bufpt++; /* point to next free slot */
} else { /* etEXP or etGENERIC */
flag_dp = (precision>0 || flag_alternateform);
if (prefix) {
*(bufpt++) = prefix; /* Sign */
}
/* First digit */
*(bufpt++) = et_getdigit(&realvalue,&nsd);
if (flag_dp) {
*(bufpt++) = '.'; /* Decimal point */
}
while((precision--) > 0) {
*(bufpt++) = et_getdigit(&realvalue,
&nsd);
}
bufpt--; /* point to last digit */
if (flag_rtz && flag_dp) {
/* Remove tail zeros */
while(bufpt >= buf && *bufpt == '0') {
*(bufpt--) = 0;
}
if (bufpt >= buf && *bufpt == '.' ) {
*(bufpt--) = 0;
}
}
bufpt++; /* point to next free slot */
if (exp || flag_exp) {
*(bufpt++) = infop->charset[0];
if (exp < 0) { /* sign of exp */
*(bufpt++) = '-';
exp = -exp;
} else {
*(bufpt++) = '+';
}
if (exp >= 100) {
/* 100's digit */
*(bufpt++) = (exp/100) + '0';
exp %= 100;
}
/* 10's digit */
*(bufpt++) = exp/10+'0';
/* 1's digit */
*(bufpt++) = exp%10+'0';
}
}
/*
* The converted number is in buf[] and zero
* terminated. Output it. Note that the number is
* in the usual order, not reversed as with integer
* conversions.
*/
length = bufpt - buf;
bufpt = buf;
/*
* Special Case: Add leading zeros if the
* flag_zeropad flag is set and we are not left
* justified.
*/
if (flag_zeropad && !flag_leftjustify &&
length < width) {
int i;
int nPad = width - length;
for(i = width; i >= nPad; i--) {
bufpt[i] = bufpt[i - nPad];
}
i = (prefix != 0);
while(nPad--)
bufpt[i++] = '0';
length = width;
}
#endif
break;
case etSIZE:
*(va_arg(ap,int*)) = count;
length = width = 0;
break;
case etPERCENT:
buf[0] = '%';
bufpt = buf;
length = 1;
break;
case etCHARLIT: /* FALLTHROUGH */
case etCHARX:
c = buf[0] = (xtype == etCHARX ?
va_arg(ap, int) : *++fmt);
if (precision >= 0) {
for(idx = 1; idx < precision; idx++) {
buf[idx] = c;
}
length = precision;
} else {
length = 1;
}
bufpt = buf;
break;
case etSTRING:
case etDYNSTRING:
bufpt = va_arg(ap, char*);
if (bufpt == 0) {
bufpt = "";
} else if (xtype == etDYNSTRING) {
extra = bufpt;
}
length = strlen(bufpt);
if (precision >= 0 && precision < length ) {
length = precision;
}
break;
case etSQLESCAPE: /* FALLTHROUGH */
case etSQLESCAPE2:
{
int i, j, n, c, isnull;
char *arg = va_arg(ap,char*);
isnull = (arg == 0);
if( isnull ) arg = (xtype == etSQLESCAPE2 ?
"NULL" : "(NULL)");
for(i = n = 0; (c = arg[i]) != 0; i++) {
if (c == '\'')
n++;
}
n += i + 1 + ((!isnull && xtype == etSQLESCAPE2) ?
2 : 0);
if (n > etBUFSIZE) {
if (__dbsql_calloc(dbp, 1, n, extra) == ENOMEM)
return -1;
bufpt = extra;
} else {
bufpt = buf;
}
j = 0;
if (!isnull && xtype == etSQLESCAPE2)
bufpt[j++] = '\'';
for(i = 0; (c = arg[i]) != 0; i++) {
bufpt[j++] = c;
if (c == '\'')
bufpt[j++] = c;
}
if (!isnull && xtype == etSQLESCAPE2)
bufpt[j++] = '\'';
bufpt[j] = 0;
length = j;
if (precision >= 0 && precision < length)
length = precision;
}
break;
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1 + (c != 0);
(*func)(arg, "%", idx);
count += idx;
if (c == 0)
fmt--;
break;
} /* End switch over the format type */
/*
* The text of the conversion is pointed to by "bufpt" and is
* "length" characters long. The field width is "width". Do
* the output.
*/
if (!flag_leftjustify) {
register int nspace;
nspace = width - length;
if (nspace > 0) {
count += nspace;
while(nspace >= etSPACESIZE) {
(*func)(arg, spaces, etSPACESIZE);
nspace -= etSPACESIZE;
}
if (nspace > 0)
(*func)(arg, spaces, nspace);
}
}
if (length > 0) {
(*func)(arg, bufpt, length);
count += length;
}
if (flag_leftjustify) {
register int nspace;
nspace = width - length;
if (nspace > 0) {
count += nspace;
while(nspace >= etSPACESIZE) {
(*func)(arg, spaces, etSPACESIZE);
nspace -= etSPACESIZE;
}
if (nspace > 0)
(*func)(arg, spaces, nspace);
}
}
if (extra) {
if (xtype == etDYNSTRING) {
__dbsql_free(dbp, extra); /* TODO which free? */
} else {
__dbsql_free(dbp, extra);
}
}
} /* End for loop over the format string */
return errorflag ? -1 : count;
}
/*
* __mout --
* This function implements the callback from vxprintf.
* This routine add nNewChar characters of text in zNewText to
* the sgMprintf structure pointed to by "arg".
*
* STATIC: static void mout __P((void *, char *, int));
*/
static void
__mout(void* arg, char* zNewText, int nNewChar)
{
xvprintf_t *pM = (xvprintf_t*)arg;
if (pM->len + nNewChar + 1 > pM->amt) {
pM->amt = pM->len + (nNewChar * 2) + 1;
if (pM->text == pM->base) {
__dbsql_calloc(NULL, 1, pM->amt, &pM->text);
if (pM->text && pM->len)
memcpy(pM->text, pM->base, pM->len);
} else {
if (__dbsql_realloc(NULL, pM->amt, &pM->text) == ENOMEM) {
__dbsql_free(NULL, pM->text);
pM->len = 0;
pM->amt = 0;
pM->text = 0;
}
}
}
if (pM->text) {
memcpy(&pM->text[pM->len], zNewText, nNewChar);
pM->len += nNewChar;
pM->text[pM->len] = 0;
}
}
/*
* xvprintf --
*
* PUBLIC: char *xvprintf __P((DBSQL *, const char *, va_list));
*/
char *
xvprintf(dbp, fmt, ap)
DBSQL *dbp;
const char *fmt;
va_list ap;
{
xvprintf_t s;
char *new;
char buf[200];
s.len = 0;
s.text = buf;
s.amt = sizeof(buf);
s.base = buf;
__et_printf(dbp, __mout, &s, fmt, ap);
s.text[s.len] = 0;
__dbsql_malloc(dbp, s.len + 1, &new);
if (new)
strcpy(new, s.text);
if (s.text != s.base)
__dbsql_free(dbp, s.text);
return new;
}
#ifdef CONFIG_TEST
/*
* xprintf --
*
* PUBLIC: char *xprintf __P((DBSQL *, const char *, ...));
*/
char *
#ifdef STDC_HEADERS
xprintf(DBSQL *dbp, const char *fmt, ...)
#else
xprintf(dbp, fmt, va_alist)
DBSQL *dbp;
const char *fmt;
va_dcl
#endif
{
char *result;
va_list ap;
va_start(ap, fmt);
result = xvprintf(dbp, fmt, ap);
va_end(ap);
return result;
}
#endif

View file

@ -1,163 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql.h"
#include "dbsql_config.h"
#include "db_int.h"
#include <string.h>
/*
* __dbsql_umalloc --
* A malloc(3) function that will use use the _os_umalloc call of DB
* to obtain memory.
*
* PUBLIC: int __dbsql_umalloc __P((DBSQL *, size_t, void *));
*/
int
__dbsql_umalloc(DBSQL* dbp, size_t size, void* storep)
{
return (__os_umalloc((dbp ? dbp->dbenv : NULL), size, storep));
}
/*
* __dbsql_urealloc --
* realloc(3) counterpart to __dbsql_umalloc.
*
* PUBLIC: int __dbsql_urealloc __P((DBSQL *, size_t, void *));
*/
int
__dbsql_urealloc(DBSQL* dbp, size_t size, void* storep)
{
return (__os_urealloc((dbp ? dbp->dbenv : NULL), size, storep));
}
/*
* __dbsql_ufree --
* free(3) counterpart to __dbsql_umalloc.
*
* PUBLIC: void __dbsql_ufree __P((DBSQL *, void *));
*/
void
__dbsql_ufree(DBSQL* dbp, void* ptr)
{
__os_ufree((dbp ? dbp->dbenv : NULL), ptr);
}
/*
* __dbsql_strdup --
* The __dbsql_strdup(3) function for DBSQL.
*
* PUBLIC: int __dbsql_strdup __P((DBSQL *, const char *, void *));
*/
int
__dbsql_strdup(dbp, str, storep)
DBSQL *dbp;
const char *str;
void *storep;
{
return (__os_strdup((dbp ? dbp->dbenv : NULL), str, storep));
}
/*
* __dbsql_strndup --
* The __dbsql_strndup(3) function for DBSQL.
*
* PUBLIC: int __dbsql_strndup __P((DBSQL *, const char *, void *, size_t));
*/
int
__dbsql_strndup(dbp, str, storep, len)
DBSQL *dbp;
const char *str;
void *storep;
size_t len;
{
size_t size;
int ret;
void *p;
DB_ENV *dbenv = (dbp->dbenv ? NULL : dbp->dbenv);
*(void **)storep = NULL;
if (len > strlen(str))
size = strlen(str);
else
size = len;
if ((ret = __os_calloc(dbenv, 1, size + 1, &p)) != 0)
return (ret);
memcpy(p, str, size);
*(void **)storep = p;
return (0);
}
/*
* __dbsql_calloc --
* The calloc(3) function for DBSQL.
*
* PUBLIC: int __dbsql_calloc __P((DBSQL *, size_t, size_t, void *));
*/
int
__dbsql_calloc(dbp, num, size, storep)
DBSQL *dbp;
size_t num, size;
void *storep;
{
return (__os_calloc((dbp ? dbp->dbenv : NULL), num, size,
storep));
}
/*
* __dbsql_malloc --
* The malloc(3) function for DBSQL.
*
* PUBLIC: int __dbsql_malloc __P((DBSQL *, size_t, void *));
*/
int
__dbsql_malloc(DBSQL* dbp, size_t size, void* storep)
{
return (__os_malloc((dbp ? dbp->dbenv : NULL), size, storep));
}
/*
* __dbsql_realloc --
* The realloc(3) function for DBSQL.
*
* PUBLIC: int __dbsql_realloc __P((DBSQL *, size_t, void *));
*/
int
__dbsql_realloc(DBSQL* dbp, size_t size, void* storep)
{
return (__os_realloc((dbp ? dbp->dbenv : NULL), size, storep));
}
/*
* __dbsql_free --
* The free(3) function for DBSQL.
*
* PUBLIC: void __dbsql_free __P((DBSQL *, void *));
*/
void
__dbsql_free(DBSQL* dbp, void* ptr)
{
__os_free((dbp ? dbp->dbenv : NULL), ptr);
}

View file

@ -1,105 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
/*
* __dbsql_atof --
* The string z[] is an ascii representation of a real number.
* Convert this string to a double.
*
* This routine assumes that z[] really is a valid number. If it
* is not, the result is undefined.
*
* This routine is used instead of the library atof() function because
* the library atof() might want to use "," as the decimal point instead
* of "." depending on how locale is set. But that would cause problems
* for SQL. So this routine always uses "." regardless of locale.
*
* PUBLIC: double __dbsql_atof __P((const char *));
*/
double
__dbsql_atof(z)
const char *z;
{
int sign = 1;
long_double_t v1 = 0.0;
if (*z == '-') {
sign = -1;
z++;
} else if (*z == '+') {
z++;
}
while(isdigit(*z)) {
v1 = v1 * 10.0 + (*z - '0');
z++;
}
if (*z == '.') {
long_double_t divisor = 1.0;
z++;
while(isdigit(*z)) {
v1 = v1 * 10.0 + (*z - '0');
divisor *= 10.0;
z++;
}
v1 /= divisor;
}
if (*z == 'e' || *z == 'E') {
int esign = 1;
int eval = 0;
long_double_t scale = 1.0;
z++;
if (*z == '-') {
esign = -1;
z++;
} else if (*z == '+') {
z++;
}
while(isdigit(*z)) {
eval = eval * 10 + *z - '0';
z++;
}
while(eval >= 64) {
scale *= 1.0e+64;
eval -= 64;
}
while(eval >= 16) {
scale *= 1.0e+16;
eval -= 16;
}
while(eval >= 4) {
scale *= 1.0e+4;
eval -= 4;
}
while(eval >= 1) {
scale *= 1.0e+1;
eval -= 1;
}
if (esign < 0) {
v1 /= scale;
} else {
v1 *= scale;
}
}
return sign < 0 ? -v1 : v1;
}

View file

@ -1,58 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
/*
* __dbsql_atoi --
* Return TRUE if 'str' is a 32-bit signed integer and write
* the value of the integer into '*num'. If 'str' is not an integer
* or is an integer that is too large to be expressed with just 32
* bits, then return false.
*
* PUBLIC: int __dbsql_atoi __P((const char *, int *));
*/
int
__dbsql_atoi(str, num)
const char *str;
int *num;
{
int v = 0;
int neg;
int i, c;
if (*str == '-') {
neg = 1;
str++;
} else if (*str == '+') {
neg = 0;
str++;
} else {
neg = 0;
}
for (i = 0; (c = str[i]) >= '0' && c <= '9'; i++) {
v = (v * 10) + c - '0';
}
*num = neg ? -v : v;
return (c == 0 && i > 0 &&
(i < 10 || (i == 10 && memcmp(str,"2147483647", 10) <= 0)));
}

View file

@ -1,461 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql_config.h"
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* Declare STDERR_FILENO. */
#endif
#include "dbsql_int.h"
#ifdef DIAGNOSTIC
/*
* __dbsql_assert --
* Error when an assertion fails. Only checked if #DIAGNOSTIC defined.
*
* PUBLIC: #ifdef DIAGNOSTIC
* PUBLIC: void __dbsql_assert __P((const char *, const char *, int));
* PUBLIC: #endif
*/
void
__dbsql_assert(failedexpr, file, line)
const char *failedexpr, *file;
int line;
{
(void)fprintf(stderr,
"__dbsql_assert: \"%s\" failed: file \"%s\", line %d\n",
failedexpr, file, line);
(void)fflush(stderr);
/* We want a stack trace of how this could possibly happen. */
abort();
/* NOTREACHED */
}
#endif
/*
* __dbsql_panic_msg --
* Just report that someone else paniced.
*
* PUBLIC: int __dbsql_panic_msg __P((DBSQL *));
*/
int
__dbsql_panic_msg(DBSQL* dbp)
{
__dbsql_err(dbp, "PANIC: fatal database error detected; run recovery");
if (dbp && dbp->dbsql_paniccall != NULL)
dbp->dbsql_paniccall(dbp, DB_RUNRECOVERY);
return (DB_RUNRECOVERY);
}
/*
* __dbsql_panic --
* Lock out the database due to unrecoverable error.
*
* PUBLIC: int __dbsql_panic __P((DBSQL *, int));
*/
int
__dbsql_panic(DBSQL* dbp, int errval)
{
if (dbp != NULL) {
PANIC_SET(dbp, 1);
__dbsql_err(dbp, "PANIC: %s", dbsql_strerror(errval));
if (dbp->dbsql_paniccall != NULL)
dbp->dbsql_paniccall(dbp, errval);
}
#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST)
/*
* We want a stack trace of how this could possibly happen.
*
* Don't drop core if it's the test suite -- it's reasonable for the
* test suite to check to make sure that DBSQL_RUNRECOVERY is returned
* under certain conditions.
*/
abort();
#endif
/*
* Chaos reigns within.
* Reflect, repent, and reboot.
* Order shall return.
*/
return (DBSQL_RUNRECOVERY);
}
/*
* dbsql_strerror --
* ANSI C strerror(3) for DBSQL.
*
* EXTERN: char *dbsql_strerror __P((int));
*/
char *
dbsql_strerror(int error)
{
char *p;
if (error == 0)
return ("Successful return: 0");
if (error > 0) {
if ((p = strerror(error)) != NULL)
return (p);
goto unknown_err;
}
if (error <= -30999 && error >= -30800) {
if ((p = db_strerror(error)) != NULL)
return (p);
goto unknown_err;
}
/*
* !!!
* The Tcl API requires that some of these return strings be compared
* against strings stored in application scripts. So, any of these
* errors that do not invariably result in a Tcl exception may not be
* altered.
*/
switch (error) {
case DBSQL_ERROR:
return ("DBSQL_ERROR: SQL logic error or missing database");
case DBSQL_INTERNAL:
return ("DBSQL_INTERNAL: Internal implementation flaw");
case DBSQL_PERM:
return ("DBSQL_PERM: Access denied due to permissions.");
case DBSQL_ABORT:
return ("DBSQL_ABORT: Callback requested query abort");
case DBSQL_BUSY:
return ("DBSQL_BUSY: Database is locked");
case DBSQL_LOCKED:
return ("DBSQL_LOCKED: Database table is locked");
case DBSQL_NOMEM:
return ("DBSQL_NOMEM: Unable to allocate additional memory.");
case DBSQL_READONLY:
return
("DBSQL_READONLY: Attempt to write a readonly database");
case DBSQL_INTERRUPTED:
return ("DBSQL_INTERRUPTED: Interrupted during processing");
case DBSQL_IOERR:
return ("DBSQL_IOERROR: Disk I/O error");
case DBSQL_NOTFOUND:
return ("DBSQL_NOTFOUND: Table or record not found");
case DBSQL_FULL:
return ("DBSQL_FULL: Database is full");
case DBSQL_CANTOPEN:
return ("DBSQL_CANTOPEN: Unable to open database file");
case DBSQL_PROTOCOL:
return ("DBSQL_PROTOCOL: Database locking protocol failure");
case DBSQL_EMPTY:
return ("DBSQL_EMPTY: Table contains no data");
case DBSQL_SCHEMA:
return ("DBSQL_SCHEMA: Database schema has changed");
case DBSQL_CONSTRAINT:
return ("DBSQL_CONSTRAINT: Constraint failed");
case DBSQL_MISMATCH:
return ("DBSQL_MISMATCH: Datatype mismatch");
case DBSQL_MISUSE:
return
("DBSQL_MISUSE: Library routine called out of sequence");
case DBSQL_AUTH:
return ("DBSQL_AUTH: Authorization denied");
case DBSQL_FORMAT:
return ("DBSQL_FORMAT: Auxiliary database format error");
case DBSQL_RANGE:
return ("DBSQL_RANGE: Bind index out of range");
case DBSQL_CORRUPT:
return ("DBSQL_CORRUPT: Data record is malformed");
case DBSQL_RUNRECOVERY:
return (
"DBSQL_RUNRECOVERY: Shutdown and run recovery on the database environment.");
case DBSQL_INVALID_NAME:
return (
"DBSQL_INVALID_NAME: Empty or invalid file name supplied");
}
unknown_err: {
/*
* !!!
* Room for a 64-bit number + slop. This buffer is only used
* if we're given an unknown error, which should never happen.
* Note, however, we're no longer thread-safe if it does.
*/
static char ebuf[40];
(void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error);
return (ebuf);
}
}
/*
* __dbsql_err --
* Standard DBSQL error routine. The same as errx, except we don't write
* to stderr if no output mechanism was specified.
*
* PUBLIC: void __dbsql_err __P((const DBSQL *, const char *, ...))
* PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3)));
*/
void
#ifdef STDC_HEADERS
__dbsql_err(const DBSQL *dbp, const char *fmt, ...)
#else
__dbsql_err(dbp, fmt, va_alist)
const DBSQL *dbp;
const char *fmt;
va_dcl
#endif
{
DBSQL_REAL_ERR(dbp, 0, 0, 0, fmt);
}
#ifndef HAVE_VSNPRINTF
#define OVERFLOW_ERROR "internal buffer overflow, process aborted\n"
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
#endif
/*
* __dbsql_errcall --
* Do the error message work for callback functions.
*
* PUBLIC: void __dbsql_errcall __P((const DBSQL *, int, int, const char *,
* PUBLIC: va_list));
*/
void
__dbsql_errcall(dbp, error, error_set, fmt, ap)
const DBSQL *dbp;
int error, error_set;
const char *fmt;
va_list ap;
{
char *p;
char errbuf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
p = errbuf;
if (fmt != NULL)
p += vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
if (error_set)
p += snprintf(p,
sizeof(errbuf) - (size_t)(p - errbuf), ": %s",
dbsql_strerror(error));
#ifndef HAVE_VSNPRINTF
/*
* !!!
* We're potentially manipulating strings handed us by the application,
* and on systems without a real snprintf() the sprintf() calls could
* have overflowed the buffer. We can't do anything about it now, but
* we don't want to return control to the application, we might have
* overwritten the stack with a Trojan horse. We're not trying to do
* anything recoverable here because systems without snprintf support
* are pretty rare anymore.
*/
if ((size_t)(p - errbuf) > sizeof(errbuf)) {
IGNORE_RESULT(write(
STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1));
abort();
/* NOTREACHED */
}
#endif
dbp->dbsql_errcall(dbp->dbsql_errpfx, errbuf);
}
/*
* __dbsql_errfile --
* Do the error message work for FILE *s.
*
* PUBLIC: void __dbsql_errfile
* PUBLIC: __P((const DBSQL *, int, int, const char *, va_list));
*/
void
__dbsql_errfile(dbp, error, error_set, fmt, ap)
const DBSQL *dbp;
int error, error_set;
const char *fmt;
va_list ap;
{
FILE *fp;
fp = dbp == NULL ||
dbp->dbsql_errfile == NULL ? stderr : dbp->dbsql_errfile;
if (dbp != NULL && dbp->dbsql_errpfx != NULL)
(void)fprintf(fp, "%s: ", dbp->dbsql_errpfx);
if (fmt != NULL) {
(void)vfprintf(fp, fmt, ap);
if (error_set)
(void)fprintf(fp, ": ");
}
if (error_set)
(void)fprintf(fp, "%s", dbsql_strerror(error));
(void)fprintf(fp, "\n");
(void)fflush(fp);
}
/*
* __error_msg --
* Add an error message to pParse->zErrMsg and increment pParse->nErr.
* The following formatting characters are allowed:
*
* %s Insert a string
* %z A string that should be freed after use
* %d Insert an integer
* %T Insert a token
* %S Insert the first element of a SrcList
*
* PUBLIC: void __error_msg __P((parser_t *, const char *, ...));
*/
void
#ifdef STDC_HEADERS
__error_msg(parser_t *parser, const char *fmt, ...)
#else
__error_msg(parser, fmt, va_alist)
parser_t parser;
const char *fmt;
va_dcl
#endif
{
va_list ap;
int len;
int i, j;
char *z;
static char null[] = "NULL";
parser->nErr++;
len = 1 + strlen(fmt);
va_start(ap, fmt);
for(i = 0; fmt[i]; i++) {
if (fmt[i] != '%' || fmt[i + 1] == 0)
continue;
i++;
switch(fmt[i]) {
case 'd': {
(void)va_arg(ap, int);
len += 20;
break;
}
case 'z': /* FALLTHROUGH */
case 's': {
char *z2 = va_arg(ap, char*);
if (z2 == 0)
z2 = null;
len += strlen(z2);
break;
}
case 'T': {
token_t *p = va_arg(ap, token_t*);
len += p->n;
break;
}
case 'S': {
src_list_t *p = va_arg(ap, src_list_t*);
int k = va_arg(ap, int);
DBSQL_ASSERT(p->nSrc > k && k >= 0);
len += strlen(p->a[k].zName);
if (p->a[k].zDatabase && p->a[k].zDatabase[0]) {
len += strlen(p->a[k].zDatabase) + 1;
}
break;
}
default:
len++;
break;
}
}
va_end(ap);
__dbsql_calloc(parser->db, 1, len, &z);
if (z == 0)
return;
__dbsql_free(parser->db, parser->zErrMsg);
parser->zErrMsg = z;
va_start(ap, fmt);
for(i = j = 0; fmt[i]; i++) {
if (fmt[i] != '%' || fmt[i + 1] == 0)
continue;
if (i > j) {
memcpy(z, &fmt[j], i - j);
z += i - j;
}
j = i + 2;
i++;
switch(fmt[i]) {
case 'd': {
int x = va_arg(ap, int);
sprintf(z, "%d", x);
z += strlen(z);
break;
}
case 'z': /* FALLTHROUGH */
case 's': {
int len;
char *z2 = va_arg(ap, char*);
if (z2 == 0)
z2 = null;
len = strlen(z2);
memcpy(z, z2, len);
z += len;
if (fmt[i] == 'z' && z2 != null) {
__dbsql_free(NULL, z2);
}
break;
}
case 'T': {
token_t *p = va_arg(ap, token_t*);
memcpy(z, p->z, p->n);
z += p->n;
break;
}
case 'S': {
int len;
src_list_t *p = va_arg(ap, src_list_t*);
int k = va_arg(ap, int);
assert(p->nSrc > k && k >= 0);
if (p->a[k].zDatabase && p->a[k].zDatabase[0]) {
len = strlen(p->a[k].zDatabase);
memcpy(z, p->a[k].zDatabase, len);
z += len;
*(z++) = '.';
}
len = strlen(p->a[k].zName);
memcpy(z, p->a[k].zName, len);
z += len;
break;
}
default:
*(z++) = fmt[i];
break;
}
}
va_end(ap);
if (i > j) {
memcpy(z, &fmt[j], i - j);
z += i - j;
}
DBSQL_ASSERT((z - parser->zErrMsg) < len);
*z = 0;
}

View file

@ -1,101 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "db_int.h"
#include <sys/stat.h>
/*
* __dbsql_exists --
* Returns if file exists using the __os_exists call of DB.
*
* PUBLIC: int __dbsql_exists __P((DBSQL *, const char *, int *));
*/
int
__dbsql_exists(dbp, path, isdirp)
DBSQL *dbp;
const char *path;
int *isdirp;
{
return (__os_exists((dbp ? dbp->dbenv : NULL), path, isdirp));
}
/*
* __dbsql_mkdir --
* Create a directory using the __os_mkdir call of DB.
*
* PUBLIC: int __dbsql_mkdir __P((DBSQL *, const char *, int));
*/
int
__dbsql_mkdir(dbp, path, mode)
DBSQL *dbp;
const char *path;
int mode;
{
return (__os_mkdir((dbp ? dbp->dbenv : NULL), path, mode));
}
/*
* __dbsql_omode --
* Convert a file mode from a string to an int.
*
* PUBLIC: int __dbsql_omode __P((DBSQL *, const char *));
*/
int
__dbsql_omode(dbp, mode)
DBSQL *dbp;
const char *mode;
{
u_int t;
int ret;
#define __SETMODE(offset, valid_ch, mask) { \
if (mode[offset] == (valid_ch)) \
t |= (mask); \
else if (mode[offset] != '-') \
goto format_err; \
}
t = 0;
__SETMODE(0, 'r', S_IRUSR);
__SETMODE(1, 'w', S_IWUSR);
__SETMODE(2, 'x', S_IXUSR);
__SETMODE(3, 'r', S_IRGRP);
__SETMODE(4, 'w', S_IWGRP);
__SETMODE(5, 'x', S_IXGRP);
__SETMODE(6, 'r', S_IROTH);
__SETMODE(7, 'w', S_IWOTH);
__SETMODE(8, 'x', S_IXOTH);
if (mode[9] != '\0' || t == 0) {
/*
* We disallow modes of 0 -- we use 0 to decide the application
* never configured intermediate directory permissions, and we
* shouldn't create intermediate directories. Besides, setting
* the permissions to 0 makes no sense.
*/
format_err: __dbsql_err(dbp, "illegal mode \"%s\"", mode);
return (EINVAL);
}
return t;
}

View file

@ -1,582 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
/*
* Basic hash-tables.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
/*
* __hash_init --
* Turn bulk memory into a hash table object by initializing the
* fields of the hash_t structure.
*
* 'this' is a pointer to the hash table that is to be initialized.
* 'class' is one of the constants DBSQL_HASH_INT, DBSQL_HASH_POINTER,
* DBSQL_HASH_BINARY, or DBSQL_HASH_STRING. The value of 'class'
* determines what kind of key the hash table will use. 'copy_key_p' is
* true if the hash table should make its own private copy of keys and
* false if it should just use the supplied pointer. 'copy_key_p' only
* makes sense for DBSQL_HASH_STRING and DBSQL_HASH_BINARY and is ignored
* for other key classes.
*
* PUBLIC: void __hash_init __P((hash_t *, int, int));
*/
void
__hash_init(hash_t* this, int class, int copy_key_p)
{
DBSQL_ASSERT(this != 0);
DBSQL_ASSERT(class >= DBSQL_HASH_INT && class <= DBSQL_HASH_BINARY);
this->keyClass = class;
this->copyKey = copy_key_p &&
(class==DBSQL_HASH_STRING || class==DBSQL_HASH_BINARY);
this->first = 0;
this->count = 0;
this->htsize = 0;
this->ht = 0;
}
/*
* __hash_clear --
* Remove all entries from a hash table. Reclaim all memory.
* Call this routine to delete a hash table or to reset a hash table
* to the empty state.
*
* PUBLIC: void __hash_clear __P((hash_t *));
*/
void
__hash_clear(hash_t* this)
{
hash_ele_t *elem;
DBSQL_ASSERT(this != 0);
elem = this->first;
this->first = 0;
if( this->ht )
__dbsql_free(NULL, this->ht);
this->ht = 0;
this->htsize = 0;
while(elem) {
hash_ele_t *next_elem = elem->next;
if( this->copyKey && elem->pKey ){
__dbsql_free(NULL, elem->pKey);
}
__dbsql_free(NULL, elem);
elem = next_elem;
}
this->count = 0;
}
/*
* __int_hash --
* Hash and comparison functions when the mode is DBSQL_HASH_INT
*
* STATIC: static int __int_hash __P((const void *, int));
*/
static int
__int_hash(key, len)
const void *key;
int len;
{
return len ^ (len << 8) ^ (len >> 8);
}
/*
* __int_cmp --
*
* STATIC: static int __h_int_cmp __P((const void *, int, const void *, int));
*/
static int
__h_int_cmp(k1, n1, k2, n2)
const void *k1;
int n1;
const void *k2;
int n2;
{
return n2 - n1;
}
/*
* __str_hash --
* Hash and comparison functions when the mode is DBSQL_HASH_STRING
*
* STATIC: static int __str_hash
*/
static int
__str_hash(key, len)
const void *key;
int len;
{
return __hash_ignore_case((const char*)key, len);
}
/*
* __str_cmp --
*
* STATIC: static int __h_str_cmp __P((const void *, int, const void *, int));
*/
static int
__h_str_cmp(k1, n1, k2, n2)
const void *k1;
int n1;
const void *k2;
int n2;
{
if (n1 != n2)
return (n2 - n1);
return strncasecmp((const char*)k1, (const char*)k2, n1);
}
/*
* __bin_hash --
* Hash and comparison functions when the mode is DBSQL_HASH_BINARY
*
* STATIC: static int __bin_hash __((const void *, int));
*/
static int
__bin_hash(key, len)
const void *key;
int len;
{
int h = 0;
const char *z = (const char *)key;
while(len-- > 0) {
h = (h << 3) ^ h ^ * (z++);
}
return h & 0x7fffffff;
}
/*
* __bin_cmp --
*
* STATIC: static int __h_bin_cmp __P((const void *, int, const void *, int));
*/
static int
__h_bin_cmp(k1, n1, k2, n2)
const void *k1;
int n1;
const void *k2;
int n2;
{
if (n1 != n2)
return (n2 - n1);
return memcmp(k1, k2, n1);
}
/*
* __hash_fn --
* Return a pointer to the appropriate hash function given the key class.
*
* The C syntax in this function definition may be unfamilar to some
* programmers, so we provide the following additional explanation:
*
* The name of the function is '__hash_fn'. The function takes a
* single parameter 'class'. The return value of __hash_fn()
* is a pointer to another function. Specifically, the return value
* of __hash_fn() is a pointer to a function that takes two parameters
* with types "const void*" and "int" and returns an "int".
*/
static int
(*__hash_fn(int class))(const void*, int)
{
switch(class) {
case DBSQL_HASH_INT:
return &__int_hash;
case DBSQL_HASH_STRING:
return &__str_hash;
case DBSQL_HASH_BINARY:
return &__bin_hash;;
default:
break;
}
return 0;
}
/*
* __cmp_fn --
* Return a pointer to the appropriate hash function given the key class.
*
* For help in interpreted the obscure C code in the function definition,
* see the header comment on the previous function.
*/
static int
(*__cmp_fn(int class))(const void*, int, const void*, int)
{
switch(class) {
case DBSQL_HASH_INT:
return &__h_int_cmp;
case DBSQL_HASH_STRING:
return &__h_str_cmp;
case DBSQL_HASH_BINARY:
return &__h_bin_cmp;
default:
break;
}
return 0;
}
/*
* __rehash --
* Resize the hash table so that it cantains 'new_size' buckets.
* 'new_size' must be a power of 2. The hash table might fail
* to resize if __dbsql_calloc() fails.
*
* STATIC: static void __rehash __P((hash_t *, int));
*/
static void
__rehash(hash_t* this, int new_size)
{
struct _ht *new_ht; /* The new hash table */
hash_ele_t *elem, *next_elem; /* For looping over existing elements */
hash_ele_t *x; /* Element being copied to new hash
table */
int (*hash)(const void*,int); /* The hash function */
DBSQL_ASSERT((new_size & (new_size - 1)) == 0);
if (__dbsql_calloc(NULL, new_size, sizeof(struct _ht), &new_ht) == ENOMEM)
return;
if (this->ht)
__dbsql_free(NULL, this->ht);
this->ht = new_ht;
this->htsize = new_size;
hash = __hash_fn(this->keyClass);
for (elem = this->first, this->first = 0; elem; elem = next_elem) {
int h = (*hash)(elem->pKey, elem->nKey) & (new_size - 1);
next_elem = elem->next;
x = new_ht[h].chain;
if (x) {
elem->next = x;
elem->prev = x->prev;
if (x->prev)
x->prev->next = elem;
else
this->first = elem;
x->prev = elem;
} else {
elem->next = this->first;
if (this->first)
this->first->prev = elem;
elem->prev = 0;
this->first = elem;
}
new_ht[h].chain = elem;
new_ht[h].count++;
}
}
/*
* __hash_search --
* This function locates an element in an hash table that matches
* the given key. The hash for this key has already been computed
* and is passed as the 4th parameter.
*
* STATIC: static hash_ele_t * __hash_search __P((const hast_t *, const void *,
* STATIC: int, int));
*
* this The hash_t to be searched
* key The the object of our search
* len The size of the key
* h The hash value for this key
*/
static hash_ele_t *__hash_search(this, key, len, h)
const hash_t *this;
const void *key;
int len;
int h;
{
hash_ele_t *elem;
int count;
int (*cmp)(const void*, int, const void*, int);
if (this->ht) {
elem = this->ht[h].chain;
count = this->ht[h].count;
cmp = __cmp_fn(this->keyClass);
while (count-- && elem) {
if ((*cmp)(elem->pKey, elem->nKey, key, len) == 0) {
return elem;
}
elem = elem->next;
}
}
return 0;
}
/*
* __hash_remove --
* Remove a single entry from the hash table given a pointer to that
* element and a hash on the element's key.
*
* STATIC: static void __hash_remove __P((hash_t *, hash_ele_t *, int));
*
* this The hash_t to be searched
* elem The element to be removed
* h The hash value for this key
*/
static void __hash_remove(this, elem, h)
hash_t *this;
hash_ele_t* elem;
int h;
{
if (elem->prev) {
elem->prev->next = elem->next;
} else {
this->first = elem->next;
}
if (elem->next) {
elem->next->prev = elem->prev;
}
if (this->ht[h].chain == elem) {
this->ht[h].chain = elem->next;
}
this->ht[h].count--;
if (this->ht[h].count <= 0) {
this->ht[h].chain = 0;
}
if (this->copyKey && elem->pKey) {
__dbsql_free(NULL, elem->pKey);
}
__dbsql_free(NULL, elem);
this->count--;
}
/*
* __hash_find --
* Attempt to locate an element of the hash table this with a key
* that matches 'key', 'len'. Return the data for this element if it is
* found, or NULL if there is no match.
*
* PUBLIC: void *__hash_find __P((const hash_t *, const void *, int));
*/
void *__hash_find(this, key, len)
const hash_t *this;
const void *key;
int len;
{
int h;
hash_ele_t *elem;
int (*hash)(const void*, int);
if (this == 0 || this->ht == 0)
return 0;
hash = __hash_fn(this->keyClass);
DBSQL_ASSERT(hash != 0);
h = (*hash)(key, len);
DBSQL_ASSERT((this->htsize & (this->htsize - 1)) == 0);
elem = __hash_search(this, key, len, h & (this->htsize - 1));
return (elem ? elem->data : 0);
}
/*
* __hash_insert --
* Insert an element into the hash table this. The key is 'key', 'len'
* and the data is 'data'.
*
* If no element exists with a matching key, then a new
* element is created. A copy of the key is made if the copy_key_p
* flag is set. NULL is returned.
*
* If another element already exists with the same key, then the
* new data replaces the old data and the old data is returned.
* The key is not copied in this instance. If a __dbsql_malloc fails,
* then the new data is returned and the hash table is unchanged.
*
* If the 'data' parameter to this function is NULL, then the
* element corresponding to 'key' is removed from the hash table.
*
* PUBLIC: void *__hash_insert __P((hash_t *, const void *, int, void *));
*/
void *
__hash_insert(this, key, len, data)
hash_t *this;
const void *key;
int len;
void *data;
{
int hraw; /* Raw hash value of the key */
int h; /* the hash of the key modulo hash table size */
hash_ele_t *elem; /* Used to loop thru the element list */
hash_ele_t *new_elem; /* New element added to the pH */
int (*hash)(const void*,int); /* The hash function */
DBSQL_ASSERT(this != 0);
hash = __hash_fn(this->keyClass);
DBSQL_ASSERT(hash != 0);
hraw = (*hash)(key, len);
DBSQL_ASSERT((this->htsize & (this->htsize - 1)) == 0);
h = hraw & (this->htsize - 1);
elem = __hash_search(this, key, len, h);
if (elem) {
void *old_data = elem->data;
if (data == 0) {
__hash_remove(this, elem, h);
} else {
elem->data = data;
}
return old_data;
}
if (data == 0)
return 0;
if (__dbsql_calloc(NULL, 1, sizeof(hash_ele_t), &new_elem) == ENOMEM)
return data;
if (this->copyKey && key != 0) {
if (__dbsql_calloc(NULL, 1, len, &new_elem->pKey) == ENOMEM) {
__dbsql_free(NULL, new_elem);
return data;
}
memcpy((void*)new_elem->pKey, key, len);
} else {
new_elem->pKey = (void*)key;
}
new_elem->nKey = len;
this->count++;
if (this->htsize == 0)
__rehash(this, 8);
if (this->htsize == 0) {
this->count = 0;
__dbsql_free(NULL, new_elem);
return data;
}
if (this->count > this->htsize) {
__rehash(this, this->htsize * 2);
}
DBSQL_ASSERT((this->htsize & (this->htsize - 1)) == 0);
h = hraw & (this->htsize - 1);
elem = this->ht[h].chain;
if (elem) {
new_elem->next = elem;
new_elem->prev = elem->prev;
if (elem->prev) {
elem->prev->next = new_elem;
} else {
this->first = new_elem;
}
elem->prev = new_elem;
} else {
new_elem->next = this->first;
new_elem->prev = 0;
if (this->first) {
this->first->prev = new_elem;
}
this->first = new_elem;
}
this->ht[h].count++;
this->ht[h].chain = new_elem;
new_elem->data = data;
return 0;
}
/*
* __hash_ignore_case --
* This function computes a hash on the name of a keyword.
* Case is not significant.
*
* PUBLIC: int __hash_ignore_case __P((const char *, int));
*/
int
__hash_ignore_case(z, n)
const char *z;
int n;
{
int h = 0;
if (n <= 0)
n = strlen(z);
while(n > 0) {
h = (h<<3) ^ h ^ __str_upper_to_lower[(unsigned char) * z++];
n--;
}
return h & 0x7fffffff;
}

View file

@ -1,876 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
* The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include <ctype.h>
unsigned char __str_upper_to_lower[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
252,253,254,255
};
/*
* __str_append --
* Create a string from the 2nd and subsequent arguments (up
* to the first NULL argument), store the string in memory
* obtained from __dbsql_calloc() and make the pointer indicated
* by the 1st argument point to that string. The 1st argument
* must either be NULL or point to memory obtained from
* __dbsql_calloc().
*
* PUBLIC: void __str_append __P((char **, const char *, ...));
*/
void
#ifdef STDC_HEADERS
__str_append(char **result, const char *fmt, ...)
#else
__str_append(result, fmt, va_alist)
char **result;
const char *fmt;
va_dcl
#endif
{
va_list ap;
size_t len;
const char *tmp;
char *r;
if (result == 0)
return;
len = strlen(fmt) + 1;
va_start(ap, fmt);
while((tmp = va_arg(ap, const char*)) != NULL) {
len += strlen(tmp);
}
va_end(ap);
__dbsql_free(NULL, *result);
if (__dbsql_calloc(NULL, 1, len, &r) == ENOMEM)
return;
*result = r;
strcpy(r, fmt);
r += strlen(r);
va_start(ap, fmt);
while((tmp = va_arg(ap, const char*)) != NULL) {
strcpy(r, tmp);
r += strlen(r);
}
va_end(ap);
}
/*
* __str_nappend --
* Works like __str_append, but each string is now followed by
* a length integer which specifies how much of the source string
* to copy (in bytes). -1 means use the whole string. The 1st
* argument must either be NULL or point to memory obtained from
* __dbsql_calloc().
*
* PUBLIC: void __str_nappend __P((char **, ...));
*/
void
#ifdef STDC_HEADERS
__str_nappend(char **result, ...)
#else
__str_nappend(result, va_alist)
char **result;
va_dcl
#endif
{
va_list ap;
size_t len;
const char *tmp;
char *r;
unsigned long n;
if (result == 0)
return;
len = 0;
va_start(ap, result);
while((tmp = va_arg(ap, const char*)) != NULL) {
n = va_arg(ap, int);
if (n <= 0)
n = strlen(tmp);
len += (size_t)n;
}
va_end(ap);
__dbsql_free(NULL, *result);
if (__dbsql_calloc(NULL, 1, len + 1, &r) == ENOMEM)
return;
*result = r;
va_start(ap, result);
while((tmp = va_arg(ap, const char*)) != NULL) {
n = va_arg(ap, int);
if (n <= 0)
n = strlen(tmp);
strncpy(r, tmp, n);
r += n;
}
*r = 0;
va_end(ap);
}
/*
* __str_unquote --
* Convert an SQL-style quoted string into a normal string by removing
* the quote characters. The conversion is done in-place. If the
* input does not begin with a quote character, then this routine
* is a no-op. Quotes can be of the form "'a-b-c'" or the MS-Access style
* brackets around identifiers such as: "[a-b-c]". In both cases the
* result is "a-b-c".
*
* PUBLIC: void __str_unquote __P((char *));
*/
void
__str_unquote(char* z)
{
char quote;
int i, j;
if (z == NULL)
return;
quote = z[0];
switch(quote) {
case '\'': break;
case '"': break;
case '[': quote = ']'; break;
default: return;
}
for(i = 1, j = 0; z[i]; i++) {
if (z[i] == quote) {
if (z[i + 1] == quote) {
z[j++] = quote;
i++;
} else {
z[j++] = 0;
break;
}
} else {
z[j++] = z[i];
}
}
}
/*
* __str_urealloc --
* Make a duplicate of a string into memory obtained from
* __dbsql_umalloc() Free the original string using __dbsql_free().
* This routine is called on all strings that are passed outside
* the library. That way clients can free the string using
* __dbsql_ufree() rather than having to call __dbsql_free().
*
* PUBLIC: int __str_urealloc __P((char **));
*/
int
__str_urealloc(char* *pz)
{
int rc = DBSQL_SUCCESS;
char *new;
if (pz == 0 || *pz == NULL)
return rc;
if (__dbsql_umalloc(NULL, strlen(*pz) + 1, &new) == ENOMEM) {
rc = ENOMEM;
__dbsql_free(NULL, *pz);
*pz = 0;
}
strcpy(new, *pz);
__dbsql_free(NULL, *pz);
*pz = new;
return rc;
}
/*
* __str_is_numeric --
* Return TRUE if z is a pure numeric string. Return FALSE if the
* string contains any character which is not part of a number.
* An empty string is considered non-numeric.
*
* PUBLIC: int __str_is_numeric __P((const char *));
*/
int
__str_is_numeric(const char *z)
{
if (*z == '-' || *z == '+')
z++;
if (!isdigit(*z)) {
return 0;
}
z++;
while(isdigit(*z)) {
z++;
}
if (*z == '.') {
z++;
if (!isdigit(*z))
return 0;
while(isdigit(*z)) {
z++;
}
}
if (*z == 'e' || *z == 'E') {
z++;
if (*z == '+' || *z == '-')
z++;
if (!isdigit(*z))
return 0;
while(isdigit(*z)) {
z++;
}
}
return (*z == '\0');
}
#ifdef DBSQL_UTF8_ENCODING
/*
* Convert the UTF-8 character to which z points into a 31-bit
* UCS character. This only works right if z points to a well-formed
* UTF-8 string.
*/
static int __utf8_to_int(const unsigned char *z) {
int c;
static const int init_val[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 254,
255,
};
c = init_val[*(z++)];
while((0xc0 & *z) == 0x80) {
c = (c<<6) | (0x3f & *(z++));
}
return c;
}
/*
* X is a pointer to the first byte of a UTF-8 character. Increment
* X so that it points to the next character. This only works right
* if X points to a well-formed UTF-8 string.
*/
#define __next_char(X) while((0xc0 & *++(X)) == 0x80) {}
#define __char_val(X) __utf8_to_int(X)
#else /* !defined(DBSQL_UTF8_ENCODING) */
/*
* For iso8859 encoding, the next character is just the next byte.
*/
#define __next_char(X) (++(X));
#define __char_val(X) ((int)*(X))
#endif /* defined(DBSQL_UTF8_ENCODING) */
/*
* __str_glob_cmp --
* Compare two UTF-8 strings for equality where the first string can
* potentially be a "glob" expression. Return true (1) if they
* are the same and false (0) if they are different.
*
* Globbing rules:
*
* '*' Matches any sequence of zero or more characters.
*
* '?' Matches exactly one character.
*
* [...] Matches one character from the enclosed list of
* characters.
*
* [^...] Matches one character not in the enclosed list.
*
* With the [...] and [^...] matching, a ']' character can be included
* in the list by making it the first character after '[' or '^'. A
* range of characters can be specified using '-'. Example:
* "[a-z]" matches any single lower-case letter. To match a '-', make
* it the last character in the list.
*
* This routine is usually quick, but can be N**2 in the worst case.
*
* Hints: to match '*' or '?', put them in "[]". Like this:
*
* abc[*]xyz Matches "abc*xyz" only
*
* PUBLIC: int __str_glob_cmp __P((const unsigned char *,
* PUBLIC: const unsigned char *));
*/
int
__str_glob_cmp(const unsigned char *pattern, const unsigned char *string)
{
unsigned char c, c2;
int invert;
int seen;
while((c = *pattern) != 0) {
switch(c) {
case '*':
while((c = pattern[1]) == '*' || c == '?') {
if (c == '?') {
if (*string == 0)
return 0;
__next_char(string);
}
pattern++;
}
if (c == 0)
return 1;
if (c == '[') {
while(*string &&
__str_glob_cmp(&pattern[1],
string) == 0) {
__next_char(string);
}
return (*string != 0);
} else {
while((c2 = *string) != 0) {
while(c2 != 0 && c2 != c) {
c2 = *++string;
}
if (c2 == 0)
return 0;
if (__str_glob_cmp(&pattern[1],
string))
return 1;
__next_char(string);
}
return 0;
}
case '?': {
if (*string == 0)
return 0;
__next_char(string);
pattern++;
break;
}
case '[': {
int prior_c = 0;
seen = 0;
invert = 0;
c = __char_val(string);
if (c == 0)
return 0;
c2 = *++pattern;
if (c2 == '^') {
invert = 1;
c2 = *++pattern;
}
if (c2 == ']') {
if (c == ']')
seen = 1;
c2 = *++pattern;
}
while((c2 = __char_val(pattern)) != 0 && c2 != ']') {
if (c2 == '-' && pattern[1] != ']' &&
pattern[1] != 0 && prior_c > 0) {
pattern++;
c2 = __char_val(pattern);
if (c >= prior_c && c <= c2)
seen = 1;
prior_c = 0;
} else if (c == c2) {
seen = 1;
prior_c = c2;
} else {
prior_c = c2;
}
__next_char(pattern);
}
if (c2 == 0 || (seen ^ invert) == 0)
return 0;
__next_char(string);
pattern++;
break;
}
default: {
if (c != *string )
return 0;
pattern++;
string++;
break;
}
}
}
return (*string == 0);
}
/*
* __str_like_cmp --
* Compare two UTF-8 strings for equality using the "LIKE" operator of
* SQL. The '%' character matches any sequence of 0 or more
* characters and '_' matches any single character. Case is
* not significant. This routine is just an adaptation of the
* __str_glob_cmp() routine above.
*
* PUBLIC: int __str_like_cmp __P((const unsigned char *,
* PUBLIC: const unsigned char *));
*/
int
__str_like_cmp(const unsigned char *pattern, const unsigned char *string)
{
register int c;
int c2;
while((c = __str_upper_to_lower[*pattern]) != 0) {
switch(c) {
case '%': {
while((c = pattern[1]) == '%' || c == '_') {
if (c == '_') {
if (*string == 0)
return 0;
__next_char(string);
}
pattern++;
}
if (c == 0)
return 1;
c = __str_upper_to_lower[c];
while((c2 = __str_upper_to_lower[*string]) != 0) {
while(c2 != 0 && c2 != c) {
c2 = __str_upper_to_lower[*++string];
}
if (c2 == 0)
return 0;
if (__str_like_cmp(&pattern[1], string))
return 1;
__next_char(string);
}
return 0;
}
case '_': {
if (*string == 0)
return 0;
__next_char(string);
pattern++;
break;
}
default: {
if (c != __str_upper_to_lower[*string])
return 0;
pattern++;
string++;
break;
}
}
}
return (*string == 0);
}
/*
* __str_numeric_cmp --
* This comparison routine is what we use for comparison operations
* between numeric values in an SQL expression. "Numeric" is a little
* bit misleading here. What we mean is that the strings have a
* type of "numeric" from the point of view of SQL. The strings
* do not necessarily contain numbers. They could contain text.
*
* If the input strings both look like actual numbers then they
* compare in numerical order. Numerical strings are always less
* than non-numeric strings so if one input string looks like a
* number and the other does not, then the one that looks like
* a number is the smaller. Non-numeric strings compare in
* lexigraphical order (the same order as strcmp()).
*
* PUBLIC: int __str_numeric_cmp __P((const char *, const char *));
*/
int
__str_numeric_cmp(const char *left, const char *right)
{
int result;
int left_is_num, right_is_num;
if (left == 0) {
return -1;
} else if (right == 0) {
return 1;
}
left_is_num = __str_is_numeric(left);
right_is_num = __str_is_numeric(right);
if (left_is_num) {
if (!right_is_num) {
result = -1;
} else {
double rl, rr;
rl = __dbsql_atof(left);
rr = __dbsql_atof(right);
if (rl < rr){
result = -1;
} else if (rl > rr) {
result = +1;
} else {
result = 0;
}
}
} else if (right_is_num) {
result = +1;
} else {
result = strcmp(left, right);
}
return result;
}
/*
* __str_int_in32b --
* The string 'num' represents an integer. There might be some other
* information following the integer too, but that part is ignored.
* If the integer that the prefix of 'num' represents will fit in a
* 32-bit signed integer, return TRUE. Otherwise return FALSE.
*
* This routine returns FALSE for the string -2147483648 even though that
* that number will, in theory fit in a 32-bit integer. But positive
* 2147483648 will not fit in 32 bits. So it seems safer to return
* false.
*
* PUBLIC: int __str_int_in32b __P((const char *));
*/
int
__str_int_in32b(const char *num)
{
int i = 0;
char c;
if (*num == '-' || *num == '+')
num++;
while ((c = num[i]) >= '0' && c <= '9') {
i++;
}
return (i < 10 || (i == 10 && memcmp(num, "2147483647", 10) <= 0));
}
/*
* Some powers of 64. These constants are needed in the
* __str_real_as_sortable() routine below.
*/
#define _64e3 (64.0 * 64.0 * 64.0)
#define _64e4 (64.0 * 64.0 * 64.0 * 64.0)
#define _64e15 (_64e3 * _64e4 * _64e4 * _64e4)
#define _64e16 (_64e4 * _64e4 * _64e4 * _64e4)
#define _64e63 (_64e15 * _64e16 * _64e16 * _64e16)
#define _64e64 (_64e16 * _64e16 * _64e16 * _64e16)
/*
* __str_real_as_sortable --
* The following procedure converts a double-precision floating point
* number into a string. The resulting string has the property that
* two such strings comparied using strcmp() or memcmp() will give the
* same results as a numeric comparison of the original floating point
* numbers.
*
* This routine is used to generate database keys from floating point
* numbers such that the keys sort in the same order as the original
* floating point numbers even though the keys are compared using
* memcmp().
*
* The calling function should have allocated at least 14 characters
* of space for the buffer z[].
*
* PUBLIC: void __str_real_as_sortable __P((double, char *));
*/
void
__str_real_as_sortable(double r, char* z)
{
int neg;
int exp;
int cnt = 0;
/*
* This array maps integers between 0 and 63 into base-64 digits.
* The digits must be chosen such at their ASCII codes are increasing.
* This means we can not use the traditional base-64 digit set.
*/
static const char digit[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"|~";
if (r < 0.0) {
neg = 1;
r = -r;
*z++ = '-';
} else {
neg = 0;
*z++ = '0';
}
exp = 0;
if (r == 0.0) {
exp = -1024;
} else if (r < (0.5 / 64.0)) {
while(r < 0.5 / _64e64 && exp > -961) {
r *= _64e64;
exp -= 64;
}
while(r < 0.5 / _64e16 && exp > -1009) {
r *= _64e16;
exp -= 16;
}
while(r < 0.5 / _64e4 && exp > -1021) {
r *= _64e4;
exp -= 4;
}
while(r < 0.5 / 64.0 && exp > -1024) {
r *= 64.0;
exp -= 1;
}
} else if (r >= 0.5) {
while(r >= 0.5 * _64e63 && exp < 960) {
r *= 1.0 / _64e64;
exp += 64;
}
while(r >= 0.5 * _64e15 && exp < 1008) {
r *= 1.0 / _64e16;
exp += 16;
}
while(r >= 0.5 * _64e3 && exp < 1020) {
r *= 1.0 / _64e4;
exp += 4;
}
while(r >= 0.5 && exp < 1023) {
r *= 1.0/64.0;
exp += 1;
}
}
if (neg) {
exp = -exp;
r = -r;
}
exp += 1024;
r += 0.5;
if (exp < 0)
return;
if (exp >= 2048 || r >= 1.0) {
strcpy(z, "~~~~~~~~~~~~");
return;
}
*z++ = digit[(exp >> 6) & 0x3f];
*z++ = digit[exp & 0x3f];
while(r > 0.0 && cnt < 10) {
int d;
r *= 64.0;
d = (int)r;
DBSQL_ASSERT(d >= 0 && d < 64);
*z++ = digit[d & 0x3f];
r -= d;
cnt++;
}
*z = 0;
}
/*
* __str_cmp --
* This routine is used for sorting. Each key is a list of one or more
* null-terminated elements. The list is terminated by two nulls in
* a row. For example, the following text is a key with three elements
*
* Aone\000Dtwo\000Athree\000\000
*
* All elements begin with one of the characters "+-AD" and end with
* "\000" with zero or more text elements in between. Except, NULL
* elements consist of the special two-character sequence "N\000".
*
* Both arguments will have the same number of elements. This routine
* returns negative, zero, or positive if the first argument is less
* than, equal to, or greater than the first. (Result is a-b).
*
* Each element begins with one of the characters "+", "-", "A", "D".
* This character determines the sort order and collating sequence:
*
* + Sort numerically in ascending order
* - Sort numerically in descending order
* A Sort as strings in ascending order
* D Sort as strings in descending order.
*
* For the "+" and "-" sorting, pure numeric strings (strings for which
* the __str_is_numeric() function above returns TRUE) always compare
* less than strings that are not pure numerics. Non-numeric strings
* compare in memcmp() order. This is the same sort order as the
* __str_numeric_cmp() function above generates.
*
* Elements that begin with 'A' or 'D' compare in memcmp() order
* regardless of whether or not they look like a number.
*
* Note that the sort order imposed by the rules above is the same
* from the ordering defined by the "<", "<=", ">", and ">=" operators
* of expressions and for indices.
*
* PUBLIC: int __str_cmp __P((const char *, const char *));
*/
int
__str_cmp(const char *a, const char *b)
{
unsigned char dir = 0, res = 0;
int a_numeric_p, b_numeric_p;
while(res == 0 && *a && *b) {
if (a[0] == 'N' || b[0] == 'N') {
if (a[0] == b[0]) {
a += 2;
b += 2;
continue;
}
if (a[0] == 'N') {
dir = b[0];
res = -1;
} else {
dir = a[0];
res = +1;
}
break;
}
DBSQL_ASSERT(a[0] == b[0]);
if ((dir = a[0]) == 'A' || a[0] == 'D') {
res = strcmp(&a[1], &b[1]);
if (res)
break;
} else {
a_numeric_p = __str_is_numeric(&a[1]);
b_numeric_p = __str_is_numeric(&b[1]);
if (a_numeric_p) {
double rA, rB;
if (!b_numeric_p) {
res = -1;
break;
}
rA = __dbsql_atof(&a[1]);
rB = __dbsql_atof(&b[1]);
if (rA < rB) {
res = -1;
break;
}
if (rA > rB) {
res = +1;
break;
}
} else if (b_numeric_p) {
res = +1;
break;
} else {
res = strcmp(&a[1], &b[1]);
if (res)
break;
}
}
a += strlen(&a[1]) + 2;
b += strlen(&b[1]) + 2;
}
if (dir == '-' || dir == 'D')
res = -res;
return res;
}

View file

@ -1,429 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#ifndef _DBSQL_H_
#define _DBSQL_H_
#ifndef __NO_SYSTEM_INCLUDES
#include <sys/types.h>
#include <stdlib.h> /* Needed for drand48 */
#include <stdarg.h> /* Needed for the definition of va_list */
@inttypes_h_decl@
#include <stdio.h>
#endif
#include <db.h>
#if defined(__cplusplus)
extern "C" {
#endif
@DB_CONST@
@DB_PROTO1@
@DB_PROTO2@
/*
* DBSQL version information.
*/
#define DBSQL_VERSION_MAJOR @DBSQL_VERSION_MAJOR@
#define DBSQL_VERSION_MINOR @DBSQL_VERSION_MINOR@
#define DBSQL_VERSION_PATCH @DBSQL_VERSION_PATCH@
#define DBSQL_VERSION_STRING @DBSQL_VERSION_STRING@
/*
* !!!
* DBSQL uses specifically sized types. If they're not provided by
* the system, typedef them here.
*
* We protect them against multiple inclusion using __BIT_TYPES_DEFINED__,
* as does BIND and Kerberos, since we don't know for sure what #include
* files the user is using.
*
* !!!
* We also provide the standard u_int, u_long etc., if they're not provided
* by the system.
*/
#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__
@u_int8_decl@
@int16_decl@
@u_int16_decl@
@int32_decl@
@u_int32_decl@
#endif
@u_char_decl@
@u_short_decl@
@u_int_decl@
@u_long_decl@
@ssize_t_decl@
@long_double_decl@
/*
* Forward structure declarations, so we can declare pointers and
* applications can get type checking.
*/
struct __dbsql; typedef struct __dbsql DBSQL;
struct __dbsql_func; typedef struct __dbsql_func dbsql_func_t;
struct __dbsql_stmt; typedef struct __dbsql_vm dbsql_stmt_t;
struct __dbsql_db; typedef struct __dbsql_db dbsql_db_t;
struct __dbsql_value; typedef struct __dbsql_value dbsql_value_t;
typedef int (*dbsql_callback)(void *, int, char **, char **);
/*
* Name of the master database table. The master database table
* is a special table that holds the names and attributes of all
* user tables and indices.
*/
#define MASTER_NAME "master"
#define TEMP_MASTER_NAME "temp_master"
/*
* If the following macro is set to 1, then NULL values are considered
* distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
* compound queries. No other SQL database engine (among those tested)
* works this way except for OCELOT. But the SQL92 spec implies that
* this is how things should work.
*
* If the following macro is set to 0, then NULLs are indistinct for
* SELECT DISTINCT and for UNION.
*/
#define NULL_ALWAYS_DISTINCT 0
/*
* If the following macro is set to 1, then NULL values are considered
* distinct when determining whether or not two entries are the same
* in a UNIQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL,
* OCELOT, and Firebird all work. The SQL92 spec explicitly says this
* is the way things are suppose to work.
*
* If the following macro is set to 0, the NULLs are indistinct for
* a UNIQUE index. In this mode, you can only have a single NULL entry
* for a column declared UNIQUE. This is the way Informix and SQL Server
* work.
*/
#define NULL_DISTINCT_FOR_UNIQUE 1
/*
* The name of the schema tables.
*/
#define SCHEMA_TABLE(x) (x?TEMP_MASTER_NAME:MASTER_NAME)
/*
* Character Encoding:
* DBSQL supports the major character encodings.
* - ASCII (American Standard Code for Information Interchange)
* - UTF-8 (8-bit UCS/Unicode Transformation Format)
* - UTF-16 (16-bit UCS/Unicode Transformation Format)
* - ISO-8859-1 (The IANA registered the character map ISO_8859-1:1987)
*
* The following constant holds one of two strings, "UTF-8" or "iso8859",
* depending on which character encoding the library expects to see.
* The character encoding makes a difference for the LIKE and GLOB
* operators and for the LENGTH() and SUBSTR() functions.
*/
extern const char dbsql_encoding[];
#define DBSQL_ASCII_ENCODED 1
#define DBSQL_UTF8_ENCODED 2
#define DBSQL_UTF16_ENCODED 3
#define DBSQL_ISO8859_ENCODED 4
/*
* The DBSQL_UTF8_ENCODING macro is defined if the library expects to see
* UTF-8 encoded data. The DBSQL_ISO8859_ENCODING macro is defined if the
* iso8859 encoding should be used.
*/
#define DBSQL_@ENCODING@_ENCODING 1
/* DBSQL (user visible) successful return code. */
#define DBSQL_SUCCESS 0
/*
* DBSQL (user visible) error return codes.
*
* !!!
* We don't want our error returns to conflict with other packages where
* possible, so pick a base error value that's hopefully not common. We
* document that we own the error name space from -50,800 to -50,999.
*/
/* DBSQL (public) error return codes. */
#define DBSQL_ERROR (-50999)/* SQL error or missing database */
#define DBSQL_INTERNAL (-50998)/* An internal logic error */
#define DBSQL_PERM (-50997)/* Access permission denied */
#define DBSQL_ABORT (-50996)/* Callback routine requested an abort */
#define DBSQL_BUSY (-50995)/* The database file is locked */
#define DBSQL_LOCKED (-50994)/* A table in the database is locked */
#define DBSQL_NOMEM (-50993)/* A call to allocate memory failed */
#define DBSQL_READONLY (-50992)/* Attempt to write a readonly database */
#define DBSQL_INTERRUPTED (-50991)/* Operation terminated by interrupt() */
#define DBSQL_IOERR (-50990)/* Some kind of disk I/O error occurred */
#define DBSQL_FULL (-50989)/* Failed because database is full */
#define DBSQL_CANTOPEN (-50988)/* Unable to open the database file */
#define DBSQL_PROTOCOL (-50987)/* Database lock protocol error */
#define DBSQL_SCHEMA (-50986)/* The database schema changed */
#define DBSQL_CONSTRAINT (-50985)/* Abort due to constraint violation */
#define DBSQL_MISMATCH (-50984)/* Data type mismatch */
#define DBSQL_MISUSE (-50983)/* Library used incorrectly */
#define DBSQL_AUTH (-50982)/* Authorization denied */
#define DBSQL_FORMAT (-50981)/* Auxiliary database format error */
#define DBSQL_RANGE (-50980)/* 2nd parameter to bind() out of range */
#define DBSQL_ROW (-50979)/* step() has another row ready */
#define DBSQL_DONE (-50978)/* step() has finished executing */
#define DBSQL_CORRUPT (-50977)/* The data record is malformed */
#define DBSQL_RUNRECOVERY (-50976)/* Database environment requires recovery */
#define DBSQL_INVALID_NAME (-50975)/* Empty or invalid file name supplied */
/* DBSQL (private) error return codes. */
#define DBSQL_NOTFOUND (-50801)/* Table or record not found */
#define DBSQL_EMPTY (-50800)/* Database table is empty */
/*
* SQL Database Environment handle.
*/
struct __dbsql {
void *app_private; /* For use by the application. */
/* Basic API functions. */
const char *(*encoding)(void);
int (*open) __P((DBSQL *, const char *, int, char **));
int (*close) __P((DBSQL *));
int (*rowid) __P((DBSQL *));
int (*last_change_count) __P((DBSQL *));
int (*total_change_count) __P((DBSQL *));
void (*interrupt) __P((DBSQL *));
void (*set_errcall) __P((DBSQL *, void (*)(const char *, char *)));
void (*set_errfile) __P((DBSQL *, FILE *));
void (*get_errfile) __P((DBSQL *, FILE **));
void (*set_errpfx) __P((DBSQL *, const char *));
void (*get_errpfx) __P((DBSQL *, const char **));
DB_ENV *(*get_dbenv) __P((DBSQL *));
/* Callback access functions. */
void *(*set_tracecall) __P((DBSQL *, void(*)(void *, const char *),\
void *));
#ifndef DBSQL_NO_PROGRESS
void (*set_progresscall) __P((DBSQL *, int, int(*)(void*), void*));
#endif
void *(*set_commitcall) __P((DBSQL *, int(*)(void*), void*));
void (*set_busycall) __P((DBSQL *, int(*)(DBSQL *, void *, const char *, int),\
void *));
void (*set_timeout) __P((DBSQL *, int ms));
int (*get_table) __P((DBSQL *, const char *, char ***, int *,\
int *, char **));
void (*free_table) __P((char **));
int (*exec_printf) __P((DBSQL *, const char *, dbsql_callback,\
void *, char **, ...));
int (*exec_vprintf) __P((DBSQL *, const char *, dbsql_callback,\
void *, char **, va_list ap));
int (*exec_table_printf) __P((DBSQL *, const char *, char ***,\
int *, int *, char **, ...));
int (*exec_table_vprintf) __P((DBSQL *, const char *, char ***,\
int *, int *, char **, va_list));
int (*exec) __P((DBSQL *, const char *, dbsql_callback, void *,\
char **));
int (*step) __P((dbsql_stmt_t *, int *, const char ***,\
const char ***));
int (*create_function) __P((DBSQL *, const char *, int, int, void *,\
void (*)(dbsql_func_t *, int, const char**), \
void (*)(dbsql_func_t *, int, const char**), \
void (*)(dbsql_func_t *)));
int (*func_return_type) __P((DBSQL *, const char *, int));
#define DBSQL_NUMERIC (-1)
#define DBSQL_TEXT (-2)
#define DBSQL_ARGS (-3)
int (*set_authorizer) __P((DBSQL *, int (*)(void *, int, const char *,\
const char *, const char *,\
const char *), void *));
/*
* The return value of the authorization function should be one of the
* following constants:
*
define DBSQL_SUCCESS 0 Allow access (This is actually defined above) */
#define DBSQL_DENY 1 /* Abort the SQL statement with an error */
#define DBSQL_IGNORE 2 /* Don't allow access, but don't generate an error */
/*
* The second parameter to the access authorization function above will
* be one of the values below. These values signify what kind of operation
* is to be authorized. The 3rd and 4th parameters to the authorization
* function will be parameters or NULL depending on which of the following
* codes is used as the second parameter. The 5th parameter is the name
* of the database ("main", "temp", etc.) if applicable. The 6th parameter
* is the name of the inner-most trigger or view that is responsible for
* the access attempt or NULL if this access attempt is directly from
* input SQL code.
* Arg-3 Arg-4
*/
#define DBSQL_COPY 0 /* Table Name File Name */
#define DBSQL_CREATE_INDEX 1 /* Index Name Table Name */
#define DBSQL_CREATE_TABLE 2 /* Table Name NULL */
#define DBSQL_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
#define DBSQL_CREATE_TEMP_TABLE 4 /* Table Name NULL */
#define DBSQL_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
#define DBSQL_CREATE_TEMP_VIEW 6 /* View Name NULL */
#define DBSQL_CREATE_TRIGGER 7 /* Trigger Name Table Name */
#define DBSQL_CREATE_VIEW 8 /* View Name NULL */
#define DBSQL_DELETE 9 /* Table Name NULL */
#define DBSQL_DROP_INDEX 10 /* Index Name Table Name */
#define DBSQL_DROP_TABLE 11 /* Table Name NULL */
#define DBSQL_DROP_TEMP_INDEX 12 /* Index Name Table Name */
#define DBSQL_DROP_TEMP_TABLE 13 /* Table Name NULL */
#define DBSQL_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
#define DBSQL_DROP_TEMP_VIEW 15 /* View Name NULL */
#define DBSQL_DROP_TRIGGER 16 /* Trigger Name Table Name */
#define DBSQL_DROP_VIEW 17 /* View Name NULL */
#define DBSQL_INSERT 18 /* Table Name NULL */
#define DBSQL_PRAGMA 19 /* Pragma Name 1st arg or NULL */
#define DBSQL_READ 20 /* Table Name Column Name */
#define DBSQL_SELECT 21 /* NULL NULL */
#define DBSQL_TRANSACTION 22 /* NULL NULL */
#define DBSQL_UPDATE 23 /* Table Name Column Name */
#define DBSQL_ATTACH 24 /* Filename NULL */
#define DBSQL_DETACH 25 /* Database Name NULL */
/* Non-callback access functions. */
int (*prepare) __P((DBSQL *, const char *, const char **,\
dbsql_stmt_t **, char **));
int (*finalize) __P((dbsql_stmt_t *, char **));
int (*reset) __P((dbsql_stmt_t *, char **));
int (*bind) __P((dbsql_stmt_t *, int, const char *, int, int));
/*
* From here on out, fields are internal and subject to change.
*/
DB_ENV *dbenv; /* The Berkeley DB Environment */
int txn_flags;
void (*dbsql_errcall)(const char *, char *); /* Error callback */
FILE *dbsql_errfile; /* The error file */
char *dbsql_errpfx; /* The error prefix string */
void (*dbsql_paniccall)(DBSQL *, int); /* The panic callback */
int panic; /* If non-zero, shut down the application */
dbsql_db_t *aDb; /* One for each open SQL database + 2 */
int nDb; /* Number of open dbsql_db_t's open */
int flags; /* Flags, see below */
#define DBSQL_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define DBSQL_Initialized 0x00000002 /* True after initialization */
#define DBSQL_Interrupt 0x00000004 /* Cancel current operation */
#define DBSQL_InTrans 0x00000008 /* True if in a transaction */
#define DBSQL_InternChanges 0x00000010 /* Uncommitted Hash table changes */
#define DBSQL_FullColNames 0x00000020 /* Show full column names on SELECT */
#define DBSQL_CountRows 0x00000040 /* Count rows changed by INSERT,
DELETE, or UPDATE and return
the count using a callback. */
#define DBSQL_NullCallback 0x00000080 /* Invoke the callback once if the
result set is empty */
#define DBSQL_ReportTypes 0x00000200 /* Include information on datatypes
in 4th argument of callback */
#define DBSQL_DurableTemp 0x00000400 /* Back temp databases on disk. */
#define DBSQL_Threaded 0x00000800 /* Set when we're expected to be
thread safe. */
u_int8_t want_to_close; /* Close after all VDBEs are deallocated */
u_int32_t next_sig; /* Next value of aDb[0].schema_sig */
int nTable; /* Number of tables in the database */
void *pBusyArg; /* 1st Argument to the busy callback */
int (*xBusyCallback)(DBSQL *, void *, const char*, int);
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*);/* Invoked at every commit. */
void *fns; /* All functions that can be in SQL exprs */
int lastRowid; /* ROWID of most recent insert */
int priorNewRowid; /* Last generated ROWID */
int onError; /* Default conflict algorithm */
int magic; /* Magic number to detect library misuse */
#define DBSQL_STATUS_OPEN 0xa029a697 /* Database is open */
#define DBSQL_STATUS_CLOSED 0x9f3c2d33 /* Database is closed */
#define DBSQL_STATUS_BUSY 0xf03b7906 /* Database currently in use */
#define DBSQL_STATUS_ERROR 0xb5357930 /* An DBSQL_MISUSE error occurred */
u_int32_t _num_last_changes; /* Number of rows changed */
u_int32_t _num_total_changes; /* Total number of rows changed */
struct vdbe *pVdbe; /* List of active virtual machines */
void (*xTrace)(void*,const char*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
#ifndef DBSQL_NO_AUTH /* Access authorization functions */
int (*auth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* 1st argument to the access auth function */
#endif
#ifndef DBSQL_NO_PROGRESS
int (*xProgress)(void *);/* The progress callback */
void *pProgressArg; /* Argument to the progress callback */
int nProgressOps; /* Number of opcodes for progress callback */
#endif
u_int32_t format_version;/* The version of the representation */
};
#define DBSQL_THREAD 0x00001 /* When set the library is thread
safe. */
#define DBSQL_DURABLE_TEMP 0x00002 /* Store temp data on disk rather
than in memory */
int dbsql_create_env __P((DBSQL **, const char *, const char *, int, u_int32_t));
int dbsql_create __P((DBSQL **, DB_ENV *, u_int32_t));
int dbsql_complete_stmt __P((const char *));
char *dbsql_strerror __P((int));
const char * dbsql_version __P((int *, int *, int *));
void dbsql_set_result_null __P((dbsql_func_t *));
char *dbsql_set_result_string __P((dbsql_func_t *, const char *, int));
void dbsql_set_result_int __P((dbsql_func_t *, int));
void dbsql_set_result_int64 __P((dbsql_func_t *, int64_t));
void dbsql_set_result_blob __P((dbsql_func_t *, const void *, size_t,\
void(*)(void*)));
void dbsql_set_result_varchar __P((dbsql_func_t *, const char *, size_t,\
void(*)(void*)));
void dbsql_set_result_double __P((dbsql_func_t *, double));
void dbsql_set_result_error __P((dbsql_func_t *, const char *, int));
void *dbsql_user_data __P((dbsql_func_t *));
void *dbsql_aggregate_context __P((dbsql_func_t *, int));
int dbsql_aggregate_count __P((dbsql_func_t *));
/*
* The fifth parameter to dbsql_set_result_blob(), and
* dbsql_set_result_varchar() is a destructor used to dispose of the BLOB
* or text after DBSQL has finished with it. If the fifth argument is the
* special value DBSQL_STATIC, then the library assumes that the information
* is in static, unmanaged space and does not need to be freed. If the fifth
* argument has the value DBSQL_TRANSIENT, then DBSQL makes its own private
* copy of the data.
*/
#define DBSQL_STATIC ((void(*)(void *))0)
#define DBSQL_TRANSIENT ((void(*)(void *))-1)
/*
* Values are stored in the database in one of the following fundamental
* types. TODO
*/
#define DBSQL_INTEGER 1
#define DBSQL_FLOAT 2
#define DBSQL_VARCHAR 3
#define DBSQL_BLOB 4
#define DBSQL_NULL 5
#ifdef __cplusplus
}
#endif
#endif /* !_DBSQL_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,99 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* A TCL Shell for testing DBSQL.
*/
#include "dbsql_config.h"
#include "dbsql_int.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
static char main_loop[] =
"set line {}\n"
"while {![eof stdin]} {\n"
"if {$line!=\"\"} {\n"
"puts -nonewline \"> \"\n"
"} else {\n"
"puts -nonewline \"% \"\n"
"}\n"
"flush stdout\n"
"append line [gets stdin]\n"
"if {[info complete $line]} {\n"
"if {[catch {uplevel #0 $line} result]} {\n"
"puts stderr \"Error: $result\"\n"
"} elseif {$result!=\"\"} {\n"
"puts $result\n"
"}\n"
"set line {}\n"
"} else {\n"
"append line \\n\n"
"}\n"
"}\n"
;
/*
* main --
*/
int
main(int argc, char* *argv)
{
int i;
const char *info;
Tcl_Interp *interp;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
dbsql_init_tcl_interface(interp);
#ifdef CONFIG_TEST
extern int Sqlitetest1_Init(Tcl_Interp*);
extern int Sqlitetest2_Init(Tcl_Interp*);
extern int Sqlitetest3_Init(Tcl_Interp*);
extern int Sqlitetest4_Init(Tcl_Interp*);
extern int Md5_Init(Tcl_Interp*);
Sqlitetest1_Init(interp);
Sqlitetest2_Init(interp);
Sqlitetest3_Init(interp);
Sqlitetest4_Init(interp);
Md5_Init(interp);
#endif
if (argc >= 2) {
Tcl_SetVar(interp, "argv0", argv[1], TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "argv", "", TCL_GLOBAL_ONLY);
for (i = 2; i < argc; i++) {
Tcl_SetVar(interp, "argv", argv[i],
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT |
TCL_APPEND_VALUE);
}
if (Tcl_EvalFile(interp, argv[1]) != TCL_OK) {
info = Tcl_GetVar(interp, "errorInfo",
TCL_GLOBAL_ONLY);
if (info == 0)
info = interp->result;
fprintf(stderr, "%s: %s\n", *argv, info);
return 1;
}
} else {
Tcl_GlobalEval(interp, main_loop);
}
return 0;
}

View file

@ -1,41 +0,0 @@
/* DO NOT EDIT: automatically built by dist/s_include. */
#ifndef _clib_ext_h_
#define _clib_ext_h_
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef HAVE_GETOPT
int getopt __P((int, char * const *, const char *));
#endif
#ifndef HAVE_MEMCMP
int memcmp __P((const void *, const void *, size_t));
#endif
#ifndef HAVE_SRAND48_R
int srand48_r __P((struct drand48_data *));
#endif
int rand8_r __P((struct drand48_data *, u_int8_t *));
int rand32_r __P((struct drand48_data *, u_int32_t *));
#ifndef HAVE_SNPRINTF
int snprintf __P((char *, size_t, const char *, ...));
#endif
#ifndef HAVE_STRCASECMP
int strcasecmp __P((const char *, const char *));
#endif
#ifndef HAVE_STRNCASECMP
int strncasecmp __P((const char *, const char *, size_t));
#endif
#ifndef HAVE_STRDUP
char *strdup __P((const char *));
#endif
#ifndef HAVE_STRNDUP
char *strndup __P((const char *, size_t));
#endif
char *xvprintf __P((DBSQL *, const char *, va_list));
char *xprintf __P((DBSQL *, const char *, ...));
#if defined(__cplusplus)
}
#endif
#endif /* !_clib_ext_h_ */

View file

@ -1,52 +0,0 @@
/* DO NOT EDIT: automatically built by dist/s_include. */
#ifndef _common_ext_h_
#define _common_ext_h_
#if defined(__cplusplus)
extern "C" {
#endif
int __dbsql_umalloc __P((DBSQL *, size_t, void *));
int __dbsql_urealloc __P((DBSQL *, size_t, void *));
void __dbsql_ufree __P((DBSQL *, void *));
int __dbsql_strdup __P((DBSQL *, const char *, void *));
int __dbsql_strndup __P((DBSQL *, const char *, void *, size_t));
int __dbsql_calloc __P((DBSQL *, size_t, size_t, void *));
int __dbsql_malloc __P((DBSQL *, size_t, void *));
int __dbsql_realloc __P((DBSQL *, size_t, void *));
void __dbsql_free __P((DBSQL *, void *));
double __dbsql_atof __P((const char *));
int __dbsql_atoi __P((const char *, int *));
#ifdef DIAGNOSTIC
void __dbsql_assert __P((const char *, const char *, int));
#endif
int __dbsql_panic_msg __P((DBSQL *));
int __dbsql_panic __P((DBSQL *, int));
void __dbsql_err __P((const DBSQL *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3)));
void __dbsql_errcall __P((const DBSQL *, int, int, const char *, va_list));
void __dbsql_errfile __P((const DBSQL *, int, int, const char *, va_list));
void __error_msg __P((parser_t *, const char *, ...));
int __dbsql_exists __P((DBSQL *, const char *, int *));
int __dbsql_mkdir __P((DBSQL *, const char *, int));
int __dbsql_omode __P((DBSQL *, const char *));
void __hash_init __P((hash_t *, int, int));
void __hash_clear __P((hash_t *));
void *__hash_find __P((const hash_t *, const void *, int));
void *__hash_insert __P((hash_t *, const void *, int, void *));
int __hash_ignore_case __P((const char *, int));
void __str_append __P((char **, const char *, ...));
void __str_nappend __P((char **, ...));
void __str_unquote __P((char *));
int __str_urealloc __P((char **));
int __str_is_numeric __P((const char *));
int __str_glob_cmp __P((const unsigned char *, const unsigned char *));
int __str_like_cmp __P((const unsigned char *, const unsigned char *));
int __str_numeric_cmp __P((const char *, const char *));
int __str_int_in32b __P((const char *));
void __str_real_as_sortable __P((double, char *));
int __str_cmp __P((const char *, const char *));
#if defined(__cplusplus)
}
#endif
#endif /* !_common_ext_h_ */

View file

@ -1,54 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#ifndef _DB_INT_H_
#define _DB_INT_H_
/*
* These are function prototypes to non-public API parts of DB we use
* in DBSQL. DB may have been compiled with --uniquename, so we have
* to manage that here. We also have to smooth out differences from
* version to version here as internal API is bound to change.
*/
#if defined(__cplusplus)
extern "C" {
#endif
extern int __db_omode__DB_UNIQUE_NAME__ __P((const char *));
extern int __os_calloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, size_t, void *));
extern int __os_exists__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, int *));
extern int __os_get_errno__DB_UNIQUE_NAME__ __P((void));
extern int __os_id__DB_UNIQUE_NAME__ __P((DB_ENV *, pid_t *, db_threadid_t*));
extern int __os_malloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_mkdir__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, int));
extern int __os_realloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_strdup__DB_UNIQUE_NAME__ __P((DB_ENV *, const char *, void *));
extern int __os_umalloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern int __os_urealloc__DB_UNIQUE_NAME__ __P((DB_ENV *, size_t, void *));
extern void *__ua_memcpy__DB_UNIQUE_NAME__ __P((void *, const void *, size_t));
extern void __os_free__DB_UNIQUE_NAME__ __P((DB_ENV *, void *));
extern void __os_set_errno__DB_UNIQUE_NAME__ __P((int));
extern void __os_ufree__DB_UNIQUE_NAME__ __P((DB_ENV *, void *));
#if defined(__cplusplus)
}
#endif
#endif /* !_DB_INT_H_ */

View file

@ -1,201 +0,0 @@
/* DO NOT EDIT: automatically built by dist/s_include. */
#ifndef _dbsql_ext_h_
#define _dbsql_ext_h_
#if defined(__cplusplus)
extern "C" {
#endif
int __init_databases __P((DBSQL *, char**));
int __sqldb_init __P((dbsql_db_t *, DBSQL *, const char *, int, int, int));
void __api_interrupt __P((DBSQL *));
int __api_get_table __P((DBSQL *, const char *, char ***, int *, int *, char **));
void __api_free_table __P((char **));
void __attach __P((parser_t *, token_t *, token_t *));
void __detach __P((parser_t *, token_t *));
int __ref_normalizer_ctx_init __P((ref_normalizer_ctx_t *, parser_t *, int, const char *, const token_t *));
int __ref_normalize_src_list __P((ref_normalizer_ctx_t *, src_list_t *));
int __ref_normalize_select __P((ref_normalizer_ctx_t *, select_t *));
int __ref_normalize_expr __P((ref_normalizer_ctx_t *, expr_t *));
int __ref_normalize_expr_list __P((ref_normalizer_ctx_t *, expr_list_t *));
int __ref_normalize_trigger_step __P((ref_normalizer_ctx_t *, trigger_step_t *));
int __api_set_authorizer __P((DBSQL *, int (*auth)(void*,int,const char*, const char*,const char*, const char*), void *));
void __auth_read __P((parser_t *, expr_t *, src_list_t *));
int __auth_check __P((parser_t *, int, const char *, const char *, const char *));
void __auth_context_push __P((parser_t *, auth_context_t *, const char *));
void __auth_context_pop __P((auth_context_t *));
void __parse_begin __P((parser_t *, int));
void __parse_exec __P((parser_t *));
table_t *__find_table __P((DBSQL *, const char *, const char *));
table_t *__locate_table __P((parser_t *, const char *, const char *));
index_t *__find_index __P((DBSQL *, const char *, const char *));
void __unlink_and_delete_index __P((DBSQL *, index_t *));
void __reset_internal_schema __P((DBSQL *, int));
void __rollback_internal_changes __P((DBSQL *));
void __commit_internal_changes __P((DBSQL *));
void __vdbe_delete_table __P((DBSQL *, table_t *));
char *__table_name_from_token __P((token_t *));
void __open_master_table __P((vdbe_t *, int));
void __start_table __P((parser_t *, token_t *, token_t *, int, int));
void __add_column __P((parser_t *, token_t *));
void __add_not_null __P((parser_t *, int));
void __add_column_type __P((parser_t *, token_t *, token_t *));
void __add_default_value __P((parser_t *, token_t *, int));
void __add_primary_key __P((parser_t *, id_list_t *, int));
int __collate_type __P((const char *, int));
void __add_collate_type __P((parser_t *, int));
void __change_schema_signature __P((DBSQL *, vdbe_t *));
void __ending_create_table_paren __P((parser_t *, token_t *, select_t *));
void __create_view __P((parser_t *, token_t *, token_t *, select_t *, int));
int __view_get_column_names __P((parser_t *, table_t *));
table_t *__table_from_token __P((parser_t *, token_t *));
void __drop_table __P((parser_t *, token_t *name, int));
void __add_idx_key_type __P((vdbe_t *, index_t *));
void __create_foreign_key __P((parser_t *, id_list_t *, token_t *, id_list_t *, int));
void __defer_foreign_key __P((parser_t *, int));
void __create_index __P((parser_t *, token_t *, src_list_t *, id_list_t *, int, token_t *, token_t *));
void __drop_index __P((parser_t *, src_list_t *));
id_list_t *__id_list_append __P((id_list_t *, token_t *));
src_list_t *__src_list_append __P((src_list_t *, token_t *, token_t *));
void __src_list_assign_cursors __P((parser_t *, src_list_t *));
void __src_list_add_alias __P((src_list_t *, token_t *));
void __id_list_delete __P((id_list_t *));
int __id_list_index __P((id_list_t *, const char *));
void __src_list_delete __P((src_list_t *));
void __dbsql_txn_begin __P((parser_t *, int));
void __dbsql_txn_commit __P((parser_t *));
void __dbsql_txn_abort __P((parser_t *));
void __code_verify_schema __P((parser_t *, int));
void __vdbe_prepare_write __P((parser_t*, int, int));
void __vdbe_conclude_write __P((parser_t *));
void __copy __P((parser_t *, src_list_t *, token_t *, token_t *, int));
void __register_datetime_funcs __P((DBSQL *));
table_t *__src_list_lookup __P((parser_t *, src_list_t *));
int __is_table_read_only __P((parser_t *, table_t *, int));
void __delete_from __P((parser_t *, src_list_t *, expr_t *));
void __generate_row_delete __P((DBSQL *, vdbe_t *, table_t *, int, int));
void __generate_row_index_delete __P((DBSQL *, vdbe_t *, table_t *, int, char *));
expr_t *__expr __P((int, expr_t *, expr_t *, token_t *));
void __expr_span __P((expr_t *, token_t *, token_t *));
expr_t *__expr_function __P((expr_list_t *, token_t *));
void __expr_delete __P((expr_t *));
expr_t *__expr_dup __P((expr_t *));
void __token_copy __P((token_t *, token_t *));
expr_list_t *__expr_list_dup __P((expr_list_t *));
src_list_t *__src_list_dup __P((src_list_t *));
id_list_t *__id_list_dup __P((id_list_t *));
select_t *__select_dup __P((select_t *));
expr_list_t *__expr_list_append __P((expr_list_t *, expr_t *, token_t *));
void __expr_list_delete __P((expr_list_t *));
int __expr_is_constant __P((expr_t *));
int __expr_is_integer __P((expr_t *, int *));
int __is_row_id __P((const char *));
int __expr_resolve_ids __P((parser_t *, src_list_t *, expr_list_t *, expr_t *));
int __expr_check __P((parser_t *, expr_t *, int, int *));
int __expr_type __P((expr_t *));
void __expr_code __P((parser_t *, expr_t *));
void __expr_if_false __P((parser_t *, expr_t *, int, int));
int __expr_compare __P((expr_t *, expr_t *));
int __expr_analyze_aggregates __P((parser_t *, expr_t *));
func_def_t *__find_function __P((DBSQL *, const char *, int, int, int));
void __insert __P((parser_t *, src_list_t *, expr_list_t *, select_t *, id_list_t *, int));
void __generate_constraint_checks __P((parser_t *, table_t *, int, char *, int, int, int, int));
void __complete_insertion __P((parser_t *, table_t *, int, char *, int, int, int));
void __pragma __P((parser_t *, token_t *, token_t *, int));
select_t *__select_new __P((expr_list_t *, src_list_t *, expr_t *, expr_list_t *, expr_t *, expr_list_t *, int, int, int));
int __join_type __P((parser_t *, token_t *, token_t *, token_t *));
void __select_delete __P((select_t *));
void __add_key_type __P((vdbe_t *, expr_list_t *));
void __select_unbind __P((select_t *));
vdbe_t *__parser_get_vdbe __P((parser_t *));
int __select __P((parser_t *, select_t *, int, int, select_t *, int, int *));
table_t *__select_result_set __P((parser_t *, char *, select_t *));
void __vdbe_delete_trigger_step __P((trigger_step_t *));
void __begin_trigger __P((parser_t *, token_t *, int, int, id_list_t *, src_list_t *, int, expr_t *, int));
void __finish_trigger __P((parser_t *, trigger_step_t *, token_t *));
trigger_step_t * __trigger_select_step __P((select_t *));
trigger_step_t *__trigger_insert_step __P((token_t *, id_list_t *, expr_list_t *, select_t *, int));
trigger_step_t *__trigger_update_step __P((token_t *, expr_list_t *, expr_t *, int));
trigger_step_t *__trigger_delete_step __P((token_t *, expr_t *));
void __vdbe_delete_trigger __P((trigger_t *));
void __drop_trigger __P((parser_t *, src_list_t *));
void __drop_trigger_ptr __P((parser_t *, trigger_t *, int));
int __triggers_exist __P((parser_t *, trigger_t *, int, int, int, expr_list_t *));
int __code_row_trigger __P(());
void __update __P((parser_t *, src_list_t *, expr_list_t *, expr_t *, int));
void __vacuum __P((parser_t *, token_t *));
int __execute_vacuum __P((char **, DBSQL *));
int __execute_vacuum __P((char **, DBSQL *));
where_info_t *__where_begin __P((parser_t *, src_list_t *, expr_t *, int, expr_list_t **));
void __where_end __P((where_info_t *));
int __safety_on __P((DBSQL *));
int __safety_off __P((DBSQL *));
int __safety_check __P((DBSQL *));
int __sm_bt_compare __P((DB *, const DBT *, const DBT *));
int __sm_create __P((DBSQL *, const char *, int, int, sm_t **));
int __sm_close_db __P((sm_t *));
int __sm_checkpoint __P((sm_t *));
char *__sm_get_database_name __P((sm_t *));
int __sm_begin_txn __P((sm_t *));
int __sm_commit_txn __P((sm_t *));
int __sm_abort_txn __P((sm_t *));
int __sm_cursor __P((sm_t *, int, int, sm_cursor_t **));
int __sm_close_cursor __P((sm_cursor_t *));
int __sm_moveto __P((sm_cursor_t *, const void *, int, int *));
int __sm_next __P((sm_cursor_t *, int *));
int __sm_prev __P((sm_cursor_t *, int *));
int __sm_key_size __P((sm_cursor_t *, int *));
int __sm_data_size __P((sm_cursor_t *, int *));
int __sm_key_compare __P((sm_cursor_t *, const void *, int, int, int *));
size_t __sm_key __P((sm_cursor_t *, size_t, size_t, const void *));
size_t __sm_data __P((sm_cursor_t *, size_t, size_t, char *));
int __sm_first __P((sm_cursor_t *, int *));
int __sm_last __P((sm_cursor_t *, int *));
int __sm_insert __P((sm_cursor_t *, const void *, int, const void *, int));
int __sm_delete __P((sm_cursor_t *));
int __sm_drop_table __P((sm_t *, int));
int __sm_clear_table __P((sm_t *, int));
int __sm_open_table __P((sm_t *, int *));
int __sm_create_table __P((sm_t *, int *));
int __sm_create_index __P((sm_t *, int *));
int __sm_set_format_version __P((sm_t *, int, u_int32_t));
int __sm_get_format_version __P((sm_t *, u_int32_t *));
int __sm_set_schema_sig __P((sm_t *, u_int32_t));
int __sm_get_schema_sig __P((sm_t *, u_int32_t *));
void __register_builtin_funcs __P((DBSQL *));
int __get_keyword_code __P((const char *, int));
int __run_sql_parser __P((parser_t *, const char *, char **));
int __api_step __P((dbsql_stmt_t *, int *, const char ***, const char ***));
int __vdbe_exec __P((vdbe_t *));
vdbe_t *__vdbe_create __P((DBSQL *));
void __vdbe_trace __P((vdbe_t *, FILE *));
int __vdbe_add_op __P((vdbe_t *, int, int, int));
int __vdbe_make_label __P((vdbe_t *));
void __vdbe_resolve_label __P((vdbe_t *, int));
int __vdbe_current_addr __P((vdbe_t *));
int __vdbe_add_op_list __P((vdbe_t *, int, const vdbe_op_t *));
void __vdbe_change_p1 __P((vdbe_t *, int, int));
void __vdbe_change_p2 __P((vdbe_t *, int, int));
void __vdbe_change_p3 __P((vdbe_t *, int, const char *, int));
void __vdbe_dequote_p3 __P((vdbe_t *, int));
void __vdbe_compress_space __P((vdbe_t *, int));
int __vdbe_find_op __P((vdbe_t *, int, int));
vdbe_op_t *__vdbe_get_op __P((vdbe_t *, int));
void __vdbe_print_op __P((FILE *, int, vdbe_op_t *));
int __vdbe_list __P((vdbe_t *));
void __vdbe_make_ready __P((vdbe_t *, int, dbsql_callback, void *, int));
void __vdbe_sorter_reset __P((vdbe_t *));
void __vdbe_agg_reset __P((agg_t *));
void __vdbe_keylist_free __P((keylist_t *));
void __vdbe_cleanup_cursor __P((cursor_t *));
int __vdbe_reset __P((vdbe_t *, char **));
int __vdbe_finalize __P((vdbe_t *, char **));
int __api_bind __P((dbsql_stmt_t *, int, const char *, int, int));
void __vdbe_delete __P((vdbe_t *));
int __vdbe_byte_swap __P((int));
int __vdbe_cursor_moveto __P((cursor_t *));
#if defined(__cplusplus)
}
#endif
#endif /* !_dbsql_ext_h_ */

File diff suppressed because it is too large Load diff

View file

@ -1,130 +0,0 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1998-2004
* Sleepycat Software. All rights reserved.
*/
#ifndef _DBSQL_DEBUG_H_
#define _DBSQL_DEBUG_H_
#if defined(__cplusplus)
extern "C" {
#endif
/*
* Turn on additional error checking in gcc 3.X.
*/
#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#define __attribute__(s)
#endif
/*
* When running with #DIAGNOSTIC defined, we smash memory and do memory
* guarding with a special byte value.
*/
#define CLEAR_BYTE 0xdb
#define GUARD_BYTE 0xdc
/*
* DBSQL assertions.
*
* Use __STDC__ rather than STDC_HEADERS, the #e construct is ANSI C specific.
*/
#if defined(__STDC__) && defined(DIAGNOSTIC)
#define DBSQL_ASSERT(e) ((e) ? (void)0 :__dbsql_assert(#e, __FILE__, __LINE__))
#else
#define DBSQL_ASSERT(e)
#endif
/*
* Purposly ignore return value.
*/
#define IGNORE_RESULT(x) \
(void)!(x)
/*
* "Shut that bloody compiler up!"
*
* Unused, or not-usedyet variable. We need to write and then read the
* variable, some compilers are too bloody clever by half.
*/
#define COMPQUIET(n, v) \
(n) = (v); \
(n) = (n)
/*
* Purify and other run-time tools complain about uninitialized reads/writes
* of structure fields whose only purpose is padding, as well as when heap
* memory that was never initialized is written to disk.
*/
#ifdef UMRW
#define UMRW_SET(v) (v) = 0
#else
#define UMRW_SET(v)
#endif
/*
* Error message handling. Use a macro instead of a function because va_list
* references to variadic arguments cannot be reset to the beginning of the
* variadic argument list (and then rescanned), by functions other than the
* original routine that took the variadic list of arguments.
*/
#if defined(STDC_HEADERS) || defined(__cplusplus)
#define DBSQL_REAL_ERR(dbp, error, error_set, stderr_default, fmt) { \
va_list ap; \
\
/* Call the user's callback function, if specified. */ \
va_start(ap, fmt); \
if ((dbp) != NULL && (dbp)->dbsql_errcall != NULL) \
__dbsql_errcall(dbp, error, error_set, fmt, ap); \
va_end(ap); \
\
/* Write to the user's file descriptor, if specified. */ \
va_start(ap, fmt); \
if ((dbp) != NULL && (dbp)->dbsql_errfile != NULL) \
__dbsql_errfile(dbp, error, error_set, fmt, ap); \
va_end(ap); \
\
/* \
* If we have a default and we didn't do either of the above, \
* write to the default. \
*/ \
va_start(ap, fmt); \
if ((stderr_default) && ((dbp) == NULL || \
((dbp)->dbsql_errcall == NULL && (dbp)->dbsql_errfile == NULL)))\
__dbsql_errfile(dbp, error, error_set, fmt, ap); \
va_end(ap); \
}
#else
#define DBSQL_REAL_ERR(dbp, error, error_set, stderr_default, fmt) { \
va_list ap; \
\
/* Call the user's callback function, if specified. */ \
va_start(ap); \
if ((dbp) != NULL && (dbp)->dbsql_errcall != NULL) \
__dbsql_errcall(dbp, error, error_set, fmt, ap); \
va_end(ap); \
\
/* Write to the user's file descriptor, if specified. */ \
va_start(ap); \
if ((dbp) != NULL && (dbp)->dbsql_errfile != NULL) \
__dbsql_errfile(dbp, error, error_set, fmt, ap); \
va_end(ap); \
\
/* \
* If we have a default and we didn't do either of the above, \
* write to the default. \
*/ \
va_start(ap); \
if ((stderr_default) && ((dbp) == NULL || \
((dbp)->dbsql_errcall == NULL && (dbp)->dbsql_errfile == NULL)))\
__dbsql_errfile(dbp, error, error_set, fmt, ap); \
va_end(ap); \
}
#endif
#if defined(__cplusplus)
}
#endif
#endif /* !_DBSQL_DEBUG_H_ */

View file

@ -1,25 +0,0 @@
/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996-2004
* Sleepycat Software. All rights reserved.
*/
/*******************************************************
* Global variables.
*
* Held in a single structure to minimize the name-space
* pollution.
*******************************************************/
#ifdef HAVE_VXWORKS
#include "semLib.h"
#endif
typedef struct __dbsql_globals {
const char *encoding;
int dbseq_has_wrapped;
} DBSQL_GLOBALS;
extern DBSQL_GLOBALS __dbsql_global_values;
#define DBSQL_GLOBAL(v) __dbsql_global_values.v

View file

@ -1,189 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
/*
* Copyright (c) 1990-2004
* Sleepycat Software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Redistributions in any form must be accompanied by information on
* how to obtain complete source code for the DB software and any
* accompanying software that uses the DB software. The source code
* must either be included in the distribution or be available for no
* more than the cost of distribution plus a nominal fee, and must be
* freely redistributable under reasonable conditions. For an
* executable file, complete source code means the source code for all
* modules it contains. It does not include source code for modules or
* files that typically accompany the major components of the operating
* system on which the executable file runs.
*
* THIS SOFTWARE IS PROVIDED BY ORACLE CORPORATION ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1994, 1995
*The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1995, 1996
*The President and Fellows of Harvard University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions
*/
#ifndef _DBSQL_HASH_H_
#define _DBSQL_HASH_H_
/*
* This is the header file for the generic hash-table implemenation.
*/
#if defined(__cplusplus)
extern "C" {
#endif
/* Forward declarations of structures. */
typedef struct __hash hash_t;
typedef struct __hash_ele hash_ele_t;
/*
* A complete hash table is an instance of the following structure.
* The internals of this structure are intended to be opaque -- client
* code should not attempt to access or modify the fields of this structure
* directly. Change this structure only by using the routines below.
* However, many of the "procedures" and "functions" for modifying and
* accessing this structure are really macros, so we can't really make
* this structure opaque.
*/
struct __hash {
char keyClass; /* DBSQL_HASH_INT, _POINTER, _STRING, _BINARY */
char copyKey; /* True if copy of key made on insert */
int count; /* Number of entries in this table */
hash_ele_t *first;/* The first element of the array */
int htsize; /* Number of buckets in the hash table */
struct _ht { /* the hash table */
int count; /* Number of entries with this hash */
hash_ele_t *chain; /* Pointer to first entry with this hash */
} *ht;
};
/*
* Each element in the hash table is an instance of the following
* structure. All elements are stored on a single doubly-linked list.
*
* Again, this structure is intended to be opaque, but it can't really
* be opaque because it is used by macros.
*/
struct __hash_ele {
hash_ele_t *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
void *pKey; int nKey; /* Key associated with this element */
};
/*
* There are 4 different modes of operation for a hash table:
*
* DBSQL_HASH_INT nKey is used as the key and pKey is ignored.
*
* DBSQL_HASH_STRING pKey points to a string that is nKey bytes long
* (including the null-terminator, if any). Case
* is ignored in comparisons.
*
* DBSQL_HASH_BINARY pKey points to binary data nKey bytes long.
* __os_memcmp() is used to compare keys.
*
* A copy of the key is made for DBSQL_HASH_STRING and DBSQL_HASH_BINARY
* if the copyKey parameter to HashInit is 1.
*/
#define DBSQL_HASH_INT 1
#define DBSQL_HASH_STRING 3
#define DBSQL_HASH_BINARY 4
/*
* Macros for looping over all elements of a hash table. The idiom is
* like this:
*
* hash_t h;
* hash_ele_t *p;
* ...
* for(p=__hash_first(&h); p; p=__hash_next(p)){
* SomeStructure *pData = __hash_data(p);
* // do something with pData
* }
*/
#define __hash_first(H) ((H)->first)
#define __hash_next(E) ((E)->next)
#define __hash_data(E) ((E)->data)
#define __hash_key(E) ((E)->pKey)
#define __hash_keysize(E) ((E)->nKey)
/*
* Number of entries in a hash table
*/
#define __hash_count(H) ((H)->count)
#if defined(__cplusplus)
}
#endif
#endif /* !_DBSQL_HASH_H_ */

View file

@ -1,15 +0,0 @@
/* DO NOT EDIT: automatically built by dist/s_include. */
#ifndef _os_ext_h_
#define _os_ext_h_
#if defined(__cplusplus)
extern "C" {
#endif
int __os_jtime __P((double *));
void __os_sleep __P((u_long secs, u_long usecs));
#if defined(__cplusplus)
}
#endif
#endif /* !_os_ext_h_ */

View file

@ -1,564 +0,0 @@
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: src/sys/sys/queue.h,v 1.54 2002/08/05 05:18:43 alfred Exp $
*/
#ifndef _DB_QUEUE_H_
#define _DB_QUEUE_H_
#if defined(__cplusplus)
extern "C" {
#endif
/*
* This file defines four types of data structures: singly-linked lists,
* singly-linked tail queues, lists and tail queues.
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A singly-linked tail queue is headed by a pair of pointers, one to the
* head of the list and the other to the tail of the list. The elements are
* singly linked for minimum space and pointer manipulation overhead at the
* expense of O(n) removal for arbitrary elements. New elements can be added
* to the list after an existing element, at the head of the list, or at the
* end of the list. Elements being removed from the head of the tail queue
* should use the explicit macro for this purpose for optimum efficiency.
* A singly-linked tail queue may only be traversed in the forward direction.
* Singly-linked tail queues are ideal for applications with large datasets
* and few or no removals or for implementing a FIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* For details on the use of these macros, see the queue(3) manual page.
*
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
* _NEXT + + + +
* _PREV - - - +
* _LAST - - + +
* _FOREACH + + + +
* _FOREACH_REVERSE - - - +
* _INSERT_HEAD + + + +
* _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + +
* _INSERT_TAIL - - + +
* _CONCAT - - + +
* _REMOVE_HEAD + - + -
* _REMOVE + + + +
*
*/
/*
* XXX
* We #undef all of the macros because there are incompatible versions of this
* file and these macros on various systems. What makes the problem worse is
* they are included and/or defined by system include files which we may have
* already loaded into Berkeley DB before getting here. For example, FreeBSD's
* <rpc/rpc.h> includes its system <sys/queue.h>, and VxWorks UnixLib.h defines
* several of the LIST_XXX macros. Visual C.NET 7.0 also defines some of these
* same macros in Vc7\PlatformSDK\Include\WinNT.h. Make sure we use ours.
*/
#undef LIST_EMPTY
#undef LIST_ENTRY
#undef LIST_FIRST
#undef LIST_FOREACH
#undef LIST_HEAD
#undef LIST_HEAD_INITIALIZER
#undef LIST_INIT
#undef LIST_INSERT_AFTER
#undef LIST_INSERT_BEFORE
#undef LIST_INSERT_HEAD
#undef LIST_NEXT
#undef LIST_REMOVE
#undef QMD_TRACE_ELEM
#undef QMD_TRACE_HEAD
#undef QUEUE_MACRO_DEBUG
#undef SLIST_EMPTY
#undef SLIST_ENTRY
#undef SLIST_FIRST
#undef SLIST_FOREACH
#undef SLIST_FOREACH_PREVPTR
#undef SLIST_HEAD
#undef SLIST_HEAD_INITIALIZER
#undef SLIST_INIT
#undef SLIST_INSERT_AFTER
#undef SLIST_INSERT_HEAD
#undef SLIST_NEXT
#undef SLIST_REMOVE
#undef SLIST_REMOVE_HEAD
#undef STAILQ_CONCAT
#undef STAILQ_EMPTY
#undef STAILQ_ENTRY
#undef STAILQ_FIRST
#undef STAILQ_FOREACH
#undef STAILQ_HEAD
#undef STAILQ_HEAD_INITIALIZER
#undef STAILQ_INIT
#undef STAILQ_INSERT_AFTER
#undef STAILQ_INSERT_HEAD
#undef STAILQ_INSERT_TAIL
#undef STAILQ_LAST
#undef STAILQ_NEXT
#undef STAILQ_REMOVE
#undef STAILQ_REMOVE_HEAD
#undef STAILQ_REMOVE_HEAD_UNTIL
#undef TAILQ_CONCAT
#undef TAILQ_EMPTY
#undef TAILQ_ENTRY
#undef TAILQ_FIRST
#undef TAILQ_FOREACH
#undef TAILQ_FOREACH_REVERSE
#undef TAILQ_HEAD
#undef TAILQ_HEAD_INITIALIZER
#undef TAILQ_INIT
#undef TAILQ_INSERT_AFTER
#undef TAILQ_INSERT_BEFORE
#undef TAILQ_INSERT_HEAD
#undef TAILQ_INSERT_TAIL
#undef TAILQ_LAST
#undef TAILQ_NEXT
#undef TAILQ_PREV
#undef TAILQ_REMOVE
#undef TRACEBUF
#undef TRASHIT
#define QUEUE_MACRO_DEBUG 0
#if QUEUE_MACRO_DEBUG
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
char * lastfile;
int lastline;
char * prevfile;
int prevline;
};
#define TRACEBUF struct qm_trace trace;
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \
(head)->trace.prevfile = (head)->trace.lastfile; \
(head)->trace.lastline = __LINE__; \
(head)->trace.lastfile = __FILE__; \
} while (0)
#define QMD_TRACE_ELEM(elem) do { \
(elem)->trace.prevline = (elem)->trace.lastline; \
(elem)->trace.prevfile = (elem)->trace.lastfile; \
(elem)->trace.lastline = __LINE__; \
(elem)->trace.lastfile = __FILE__; \
} while (0)
#else
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
#define TRACEBUF
#define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */
/*
* Singly-linked List declarations.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_FOREACH(var, head, field) \
for ((var) = SLIST_FIRST((head)); \
(var); \
(var) = SLIST_NEXT((var), field))
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &SLIST_FIRST((head)); \
((var) = *(varp)) != NULL; \
(varp) = &SLIST_NEXT((var), field))
#define SLIST_INIT(head) do { \
SLIST_FIRST((head)) = NULL; \
} while (0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
SLIST_NEXT((slistelm), field) = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
SLIST_FIRST((head)) = (elm); \
} while (0)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_REMOVE(head, elm, type, field) do { \
if (SLIST_FIRST((head)) == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = SLIST_FIRST((head)); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_NEXT(curelm, field) = \
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
} \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;/* first element */ \
struct type **stqh_last;/* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (0)
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = STAILQ_FIRST((head)); \
(var); \
(var) = STAILQ_NEXT((var), field))
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_NEXT((tqelm), field) = (elm); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_FIRST((head)) = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? \
NULL : \
((struct type *) \
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if (STAILQ_FIRST((head)) == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = STAILQ_FIRST((head)); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
if ((STAILQ_NEXT(curelm, field) = \
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
} \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if ((STAILQ_FIRST((head)) = \
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
/*
* List declarations.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_FOREACH(var, head, field) \
for ((var) = LIST_FIRST((head)); \
(var); \
(var) = LIST_NEXT((var), field))
#define LIST_INIT(head) do { \
LIST_FIRST((head)) = NULL; \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
LIST_NEXT((listelm), field)->field.le_prev = \
&LIST_NEXT((elm), field); \
LIST_NEXT((listelm), field) = (elm); \
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
LIST_NEXT((elm), field) = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
LIST_FIRST((head)) = (elm); \
(elm)->field.le_prev = &LIST_FIRST((head)); \
} while (0)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_REMOVE(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL) \
LIST_NEXT((elm), field)->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
} while (0)
/*
* Tail queue declarations.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
TRACEBUF \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
TRACEBUF \
}
/*
* Tail queue functions.
*/
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_HEAD(head2); \
} \
} while (0)
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = TAILQ_FIRST((head)); \
(var); \
(var) = TAILQ_NEXT((var), field))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = TAILQ_LAST((head), headname); \
(var); \
(var) = TAILQ_PREV((var), headname, field))
#define TAILQ_INIT(head) do { \
TAILQ_FIRST((head)) = NULL; \
(head)->tqh_last = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
TAILQ_NEXT((elm), field)->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else { \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
} \
TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
TAILQ_NEXT((elm), field) = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
TAILQ_FIRST((head))->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_FIRST((head)) = (elm); \
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
TAILQ_NEXT((elm), field) = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_REMOVE(head, elm, field) do { \
if ((TAILQ_NEXT((elm), field)) != NULL) \
TAILQ_NEXT((elm), field)->field.tqe_prev = \
(elm)->field.tqe_prev; \
else { \
(head)->tqh_last = (elm)->field.tqe_prev; \
QMD_TRACE_HEAD(head); \
} \
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
TRASHIT((elm)->field.tqe_next); \
TRASHIT((elm)->field.tqe_prev); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#if defined(__cplusplus)
}
#endif
#endif /* !_DB_QUEUE_H_ */

View file

@ -1,44 +0,0 @@
/*-
* DBSQL - A SQL database engine.
*
* Copyright (C) 2007-2008 The DBSQL Group, Inc. - All rights reserved.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPL as it
* is applied to this software. View the full text of the exception in file
* LICENSE_EXCEPTIONS in the directory of this software distribution.
*
* 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
* General Public License for more details.
*/
#ifndef _LRAND48_R_H_
#define _LRAND48_R_H_
/*
* A re-entrant version of a random number generator. This
* random number generator is based on the RC4 algorithm.
*/
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef HAVE_SRAND48_R
struct drand48_data {
int init_p; /* True if initialized */
int i, j; /* State variables */
int s[256]; /* State variables */
};
#endif
#if defined(__cplusplus)
}
#endif
#endif /* !_SRAND48_R_H_ */

Some files were not shown because too many files have changed in this diff Show more