Przeglądaj źródła

add uffs (new version, new port)

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2015 bbd45198-f89e-11dd-88c7-29a3b14d5316
goprife@gmail.com 14 lat temu
rodzic
commit
0b4c769f10
100 zmienionych plików z 30480 dodań i 0 usunięć
  1. 1 0
      components/dfs/filesystems/uffs/AUTHORS
  2. 27 0
      components/dfs/filesystems/uffs/CMakeLists.txt
  3. 339 0
      components/dfs/filesystems/uffs/COPYING
  4. 275 0
      components/dfs/filesystems/uffs/Doxyfile
  5. 275 0
      components/dfs/filesystems/uffs/README
  6. 5 0
      components/dfs/filesystems/uffs/TODO
  7. 733 0
      components/dfs/filesystems/uffs/dfs_uffs.c
  8. 69 0
      components/dfs/filesystems/uffs/dfs_uffs.h
  9. BIN
      components/dfs/filesystems/uffs/doc/Understanding-UFFS.odp
  10. BIN
      components/dfs/filesystems/uffs/doc/Understanding-UFFS.pdf
  11. BIN
      components/dfs/filesystems/uffs/doc/uffs-serial-num-relationship.JPG
  12. 637 0
      components/dfs/filesystems/uffs/nand/k9f1g08_mtd.c
  13. 549 0
      components/dfs/filesystems/uffs/nand/k9f1g08_mtd_ecc_hw.c
  14. 622 0
      components/dfs/filesystems/uffs/nand/k9f1g08_mtd_ecc_soft.c
  15. 7 0
      components/dfs/filesystems/uffs/src/CMakeLists.txt
  16. 24 0
      components/dfs/filesystems/uffs/src/emu/CMakeLists.txt
  17. 643 0
      components/dfs/filesystems/uffs/src/emu/cmdline.c
  18. 83 0
      components/dfs/filesystems/uffs/src/emu/cmdline.h
  19. 657 0
      components/dfs/filesystems/uffs/src/emu/helper_cmds.c
  20. 207 0
      components/dfs/filesystems/uffs/src/emu/tags
  21. 1186 0
      components/dfs/filesystems/uffs/src/emu/test_cmds.c
  22. 113 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem.c
  23. 88 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem.h
  24. 236 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw.c
  25. 356 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw_auto.c
  26. 212 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_soft.c
  27. 232 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem_share.c
  28. 311 0
      components/dfs/filesystems/uffs/src/emu/uffs_fileem_wrap.c
  29. 22 0
      components/dfs/filesystems/uffs/src/example/CMakeLists.txt
  30. 412 0
      components/dfs/filesystems/uffs/src/example/flash-interface-example.c
  31. 158 0
      components/dfs/filesystems/uffs/src/example/static-mem-allocate.c
  32. 101 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs.h
  33. 75 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_badblock.h
  34. 107 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_blockinfo.h
  35. 178 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h
  36. 59 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_core.h
  37. 46 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_crc.h
  38. 211 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_device.h
  39. 89 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_ecc.h
  40. 151 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_fd.h
  41. 76 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_find.h
  42. 311 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_flash.h
  43. 138 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_fs.h
  44. 83 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_mem.h
  45. 89 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h
  46. 75 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_os.h
  47. 94 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_pool.h
  48. 337 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h
  49. 237 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h
  50. 160 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_types.h
  51. 64 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_utils.h
  52. 55 0
      components/dfs/filesystems/uffs/src/inc/uffs/uffs_version.h
  53. 13 0
      components/dfs/filesystems/uffs/src/platform/CMakeLists.txt
  54. 322 0
      components/dfs/filesystems/uffs/src/platform/posix/uffs_config.h
  55. 148 0
      components/dfs/filesystems/uffs/src/platform/posix/uffs_os.c
  56. 317 0
      components/dfs/filesystems/uffs/src/platform/win32/uffs_config.h
  57. 148 0
      components/dfs/filesystems/uffs/src/platform/win32/uffs_os.c
  58. 37 0
      components/dfs/filesystems/uffs/src/test/api_test/CMakeLists.txt
  59. 1168 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test.c
  60. 150 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test.h
  61. 125 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test_client_posix.c
  62. 48 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test_client_win32.c
  63. 81 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test_client_wrapper.c
  64. 283 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test_server_posix.c
  65. 194 0
      components/dfs/filesystems/uffs/src/test/api_test/api_test_server_win32.c
  66. 531 0
      components/dfs/filesystems/uffs/src/test/api_test/os_uffs.c
  67. 46 0
      components/dfs/filesystems/uffs/src/test/api_test/os_uffs.h
  68. 14 0
      components/dfs/filesystems/uffs/src/test/clients/CMakeLists.txt
  69. 35 0
      components/dfs/filesystems/uffs/src/test/clients/example-2.c
  70. 58 0
      components/dfs/filesystems/uffs/src/test/clients/example.c
  71. 22 0
      components/dfs/filesystems/uffs/src/test/scripts/_t1_sub1.ts
  72. 21 0
      components/dfs/filesystems/uffs/src/test/scripts/test1.ts
  73. 67 0
      components/dfs/filesystems/uffs/src/test/scripts/test2.ts
  74. 70 0
      components/dfs/filesystems/uffs/src/test/scripts/test_delete.ts
  75. 60 0
      components/dfs/filesystems/uffs/src/test/scripts/test_seek.ts
  76. 963 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile
  77. 138 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.arm-wince-mingw32ce-gcc
  78. 957 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.in
  79. 128 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.linux-gcc
  80. 1005 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.msc
  81. 663 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.vxworks
  82. 39 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/README
  83. 1 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/VERSION
  84. 7972 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/aclocal.m4
  85. 34 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/addopcodes.awk
  86. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/2005osaward.gif
  87. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite.eps
  88. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite.gif
  89. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLiteLogo3.tiff
  90. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite_big.gif
  91. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/nocopy.gif
  92. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/powered_by_sqlite.gif
  93. 13 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.eps
  94. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.ico
  95. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.jpg
  96. BIN
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/src_logo.gif
  97. 1535 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.guess
  98. 108 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.h
  99. 107 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.h.in
  100. 1644 0
      components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.sub

+ 1 - 0
components/dfs/filesystems/uffs/AUTHORS

@@ -0,0 +1 @@
+Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>

+ 27 - 0
components/dfs/filesystems/uffs/CMakeLists.txt

@@ -0,0 +1,27 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6 )
+PROJECT( uffs )
+
+SET(CMAKE_CXX_FLAGS_VGL "-O0 -g")
+SET(CMAKE_C_FLAGS_VGL "-O0 -g")
+
+SET(CMAKE_C_FLAGS_GCOV "-g -O0 -Wall -fprofile-arcs -ftest-coverage")
+SET(CMAKE_CXX_FLAGS_GCOV "-g -O0 -Wall -fprofile-arcs -ftest-coverage")
+SET(CMAKE_EXE_LINKER_FLAGS_GCOV "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -lgcov")
+
+IF (CMAKE_COMPILER_IS_GNUCC)
+IF (APPLE)
+        SET(CMAKE_CXX_FLAGS "-fPIC -Wall -Werror -g -rdynamic")
+        SET(CMAKE_C_FLAGS "-fPIC -Wall -Werror -g -rdynamic")
+ELSE ()
+	SET(CMAKE_CXX_FLAGS "-fPIC -Wall -Werror -Wclobbered -Wempty-body -Wignored-qualifiers -Wmissing-parameter-type -Woverride-init -Wtype-limits -Wuninitialized -g -rdynamic")
+	SET(CMAKE_C_FLAGS "-fPIC -Wall -Werror -Wclobbered -Wempty-body -Wignored-qualifiers -Wmissing-parameter-type -Woverride-init -Wtype-limits -Wuninitialized -g -rdynamic")
+ENDIF()
+ENDIF()
+
+IF (UNIX)
+	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNIX")
+	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNIX")
+ENDIF()
+
+ADD_SUBDIRECTORY( src )
+

+ 339 - 0
components/dfs/filesystems/uffs/COPYING

@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE 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.
+
+		     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
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the 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 2 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, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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.

+ 275 - 0
components/dfs/filesystems/uffs/Doxyfile

@@ -0,0 +1,275 @@
+# Doxyfile 1.4.1-KDevelop
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = uffs-doc
+PROJECT_NUMBER         = 0.1
+OUTPUT_DIRECTORY       = doc/doxygen-doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = ./
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 4
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = NO
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = YES
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = YES
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = YES
+SORT_BY_SCOPE_NAME     = YES
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = ./src
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.C \
+                         *.H \
+                         *.tlh \
+                         *.diff \
+                         *.patch \
+                         *.moc \
+                         *.xpm \
+                         *.dox
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = uffs.tag
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO

+ 275 - 0
components/dfs/filesystems/uffs/README

@@ -0,0 +1,275 @@
+UFFS: Ultra-low-cost Flash File System
+
+Project: http://uffs.sf.net/
+Blog:    http://all-about-uffs.blogspot.com/
+Q/A:     http://groups.google.com/group/uffs/
+
+Author: Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+INTRODUCTION
+------------
+
+UFFS is a nand flash file system designed for embedded system.
+
+UFFS have some unique and advanced features:
+  * Low cost: e.g. it needs only 41K bytes RAM for 64MB NAND flash (page size 2048).
+    
+  * Fast booting: it reads only a few spares from each block, typically
+    mounting a fully filled file system (Gbits) within one second.
+    
+  * Superb Reliability: 
+    - The file system is designed for the embedded system which may 
+        frequently lost power/reset without care.
+    - Journal file system, the file system will automatically rollback
+        to the last state when lost power on the middle of flash programing.
+    - When 'write' return without error, the data is guarenteed been
+        saved on flash.
+
+  * Fast file create/read/write/seek.  
+  * Bad-block tolerant, ECC enable and good ware-leveling.
+  * There is no garbage collection needed for UFFS.
+  * Support multiple NAND flash class in one system.
+  * Support bare flash hardware, no operating system needed. 
+  * Support static memory allocation (works without 'malloc').
+  * Fully simulated on PC (Windows/Linux) platform.
+
+Disadvantage:
+  * space inefficency for small files: UFFS use at least one
+   'block'(the minial erase unit for NAND flash, e.g. 16K ) for a file.
+  * maximum supported blocks: 2^16 = 65535
+
+Memory consuming example:
+    For page size = 512:
+        [VARY]Tree nodes: 16 * total_blocks 
+        [CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(512)) = 5.4K 
+        [CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K
+
+        Example 1: 128M bytes NAND, 8192 blocks, total memory cost:
+            (16 * 8192)128K + 5.4K + 4.6K = 138K bytes.
+		
+        Example 2: 32M Bytes NAND, 2048 blocks, total memory cost:
+            (16 * 2048)32K + 5.4K + 4.6K = 42K bytes.
+		
+        Example 3: 16M bytes NAND, 1024 blocks, total memory cost:
+            (16 * 1024)16K + 5.4K + 4.6K = 26K bytes.
+
+    For page size = 2048:
+        [VARY]Tree nodes: 16 * total_blocks 
+        [CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(2048)) = 20.4K 
+        [CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K
+
+        Example 1: 512M bytes NAND, 8192 blocks, total memory cost:
+            (16 * 8192)128K + 20.4K + 4.6K = 153K bytes.
+		
+        Example 2: 128M Bytes NAND, 2048 blocks, total memory cost:
+            (16 * 2048)32K + 20.4K + 4.6K = 57K bytes.
+		
+        Example 3: 64M bytes NAND, 1024 blocks, total memory cost:
+            (16 * 1024)16K + 20.4K + 4.6K = 41K bytes.
+            
+
+BUILD SIMULATOR REQUIREMENT
+---------------------------
+From V1.2.0, build uffs simulator requires 'cmake'.
+'cmake' can be downloaded from: http://www.cmake.org/
+
+or, under Debian/Ubuntu:
+  sudo apt-get install cmake
+
+BUILD SIMULATOR ON LINUX
+------------------------
+1) create a 'build' dir:
+
+mkdir -p ~/build/uffs
+
+2) create Makefiles and build:
+  cd ~/build/uffs
+  cmake <path_to_uffs>
+  make
+
+5) run simulator (interactive mode):
+  src/utils/mkuffs
+ 
+ 
+BUILD SIMULATOR ON WINDOWS
+--------------------------
+
+1) create a 'build' dir along with uffs source dir,
+ d:\build\uffs
+
+2) Create VC project files:
+  cd build\uffs
+  cmake <path_to_uffs>
+
+3) Open uffs.dsw (or uffs.sln for VC > 6 ), compile & run.
+
+ 
+LATEST SOURCE CODE
+------------------
+You can get the latest source code from git repository:
+  git clone git://uffs.git.sourceforge.net/gitroot/uffs/uffs
+
+
+CURRENT STATUS
+--------------
+UFFS 0.1.x is a working version on PC simulator, also has been ported to 
+uBase embedded OS as a 'real world' product for thousands of copies,
+it works fine so far.
+
+UFFS 0.2.0 implementes full directory.
+
+UFFS 1.0.0 is the first stable release at sf.net.
+
+UFFS 1.1.0: support NAND flash with large page size (up to 2K).
+
+UFFS 1.1.1: bug fixes. a tool for making uffs disk image.
+
+UFFS 1.1.2: bug fixes. add more Flash Class. change Licence from GNU GPLv2 to GNU LGPLv2
+
+UFFS 1.2.0: 
+  - eliminate 'current path' and relatives. Now you should use absolute path in all
+    uffs APIs. For dir, the fullname should end with '/'.
+  - allow using static memory allocation, 'malloc' is no longer needed.
+  - using cmake for building simulator.
+  - bug fixes & minor changes.
+
+UFFS 1.2.1:
+  - improve bad block management
+  - bug fixes
+  - change Licence to modified GNU GPLv2.
+
+UFFS 1.3.0:
+  - improved flash interface
+  - support hardware ECC
+  - support user defined spare layout (for customized NAND flash controller)
+  - support 4K page size
+  - no partial page program required, support MLC NAND flash
+  - reduced buffer flushes by grouping buffers
+  - structual improvments and bug fixes
+  
+UFFS v1.3.1:
+  - Tidy up three memory allocators: static, native and system.
+  - Fix bugs in flash interface example.
+  - Fix memory allocation bugs when using static memory allocator.
+  - Add flash driver interface 'WriteFullPage()'.
+  - Fix compilation errors for BlackFin DSP compiler.
+
+UFFS v1.3.2:
+  - Add POSIX like file system APIs.
+  - Bug fixes.
+  
+UFFS v1.3.3:
+  - Change Flash Interface, simplify interface.
+  - Improved bad block handling.
+  - Better support for MLC NAND flash.
+  - Added hardware ECC and RS-ECC controller emulator.
+  - Bug fixes.
+
+UFFS v1.3.4
+  - New UO_NOECC option for skipping ECC (fast reading).
+  - POSIX compliance uffs_seek().
+  - Improved unclean page detection (add new 'seal' byte in spare area).
+  - Optional page data CRC.
+  - Bug fixes.
+  - Other improvements.
+  
+LICENCE
+-------
+  From v1.2.1, UFFS is released under a modified GNU GPLv2. (the same as eCos Licence)
+  The full licence text can be found in the header of source files:
+  
+	  UFFS is free software; you can redistribute it and/or modify it under
+	  the GNU Library General Public License as published by the Free Software 
+	  Foundation; either version 2 of the License, or (at your option) any
+	  later version.
+
+	  UFFS 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
+	  or GNU Library General Public License, as applicable, for more details.
+	 
+	  You should have received a copy of the GNU General Public License
+	  and GNU Library General Public License along with UFFS; if not, write
+	  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+	  Boston, MA  02110-1301, USA.
+
+	  As a special exception, if other files instantiate templates or use
+	  macros or inline functions from this file, or you compile this file
+	  and link it with other works to produce a work based on this file,
+	  this file does not by itself cause the resulting work to be covered
+	  by the GNU General Public License. However the source code for this
+	  file must still be made available in accordance with section (3) of
+	  the GNU General Public License v2.
+	 
+	  This exception does not invalidate any other reasons why a work based
+	  on this file might be covered by the GNU General Public License.
+
+
+TESTING UFFS WITH SQLITE3 REGRESSION TEST CASES
+-----------------------------------------------
+UFFS can be tested with sqlite3 regression test cases (on Linux).
+
+1) install tcl8.5-dev on host PC:
+	apt-get install tcl8.5 tcl8.5-dev
+
+    # make sure your Linux is using tcl8.5 as the default tclsh:
+		sudo update-alternatives --config tclsh
+		(select "tclsh8.5" from the list.)
+
+2) build uffs:
+	mkdir -p ~/build/uffs
+	cd ~/build/uffs
+	cmake <path_to_uffs>
+
+3) build sqlite3:
+	cd <path_to_uffs>/src/test/sqlite3/sqlite-src-3070900
+	./configure        					 # create some build support files
+	git checkout -f Makefile config.h    # restore modified Makefile and config.h
+	make test                            # start build 'testfixture' program.
+	
+	# now you'll see something like:
+	Connect: Connection refused
+	Assert (uffs_ret == ret && ret == bak_ret) fail at /home/.../src/test/api_test/os_uffs.c:os_unlink:329: unlink("/home/.../src/test/sqlite3/sqlite-src-3070900/./test.db-journal"), unix return 0, uffs return -1, bak return -1
+	make: *** [test] Error 1
+
+4) run test cases:
+	Open two terminals.
+	on termional A:
+		cd ~/build/uffs
+		src/utils/mkuffs -t 1024
+
+		#on uffs simulator command line, enter:
+		format /
+		apisrv
+
+	on terminal B:
+		cd <path_to_uffs>/src/test/sqlite3/sqlite-src-3070900
+		./test-uffs.sh
+
+	Note: if you want to run mkuffs on another PC, for example, a Windows PC, you need to specify the IP address in test-uffs.sh.
+	
+	The test will take 1~4 hours, depends on how fast your Linux box is.
+
+
+ACKNOWLEDGMENT
+---------------
+Special thanks for your contributions to:
+(list in no particular order)
+
+* Chen Jun <chj@nlscan.com>
+* Michail <digiolog@mail.ru>
+* Sjpu <sjpu@163.com>
+* RobertGray <xennex@hotmail.com>
+* Dongbo <dongbo@ftsafe.com>
+* Cag <seucag@hotmail.com>
+* Sergey <s_sazonov@m2m-t.ru>
+* Chris Conrad <chris.conrad@halliburton.com>
+* Vladimir <decoder@rambler.ru>
+* Thien Pham <thienpham2008@yahoo.com>
+* Emmanuel Blot <eblot.ml@gmail.com>
+* Michael <yowong2@gmail.com>
+* Mick D <mick-eng@sourceforge.net>
+* Paul <paulr227@gmail.com>
+* Rogerz <rogerz.zhang@gmail.com>
+
+

+ 5 - 0
components/dfs/filesystems/uffs/TODO

@@ -0,0 +1,5 @@
+TODO list for v1.3:
+
+* New API: int uffs_SkipObject(uffs_Object *obj, int size);
+* Introduce buffer group
+* Interface to Linux MTD

+ 733 - 0
components/dfs/filesystems/uffs/dfs_uffs.c

@@ -0,0 +1,733 @@
+/*
+ * File      : rtthread.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-10-22     prife        the first version
+ * 2012-03-28     prife        use mtd device interface
+*/
+#include <rtthread.h>
+
+#include <dfs_fs.h>
+#include <dfs_def.h>
+#include <rtdevice.h>
+#include "dfs_uffs.h"
+
+#include "uffs/uffs_fd.h" /* posix file api is here */
+#include "uffs/uffs_mtb.h"
+#include "uffs/uffs_mem.h"
+#include "uffs/uffs_utils.h"
+
+static URET uffs_mount_device(struct uffs_MountTableEntrySt *work);
+static URET uffs_unmount_device(struct uffs_MountTableEntrySt *work);
+static URET uffs_UnRegisterMountTable(uffs_MountTable *mtab);
+/*
+ * RT-Thread DFS Interface for uffs
+ */
+#define UFFS_DEVICE_MAX	        2	 /* the max partions on a nand deivce*/
+#define UFFS_MOUNT_PATH_MAX     128	 /* the mount point max length */
+#define FILE_PATH_MAX	        256	 /* the longest file path */
+
+struct _nand_dev
+{
+	struct rt_mtd_nand_device * dev;
+	struct uffs_StorageAttrSt storage;
+	uffs_Device uffs_dev;
+	uffs_MountTable mount_table;
+	char mount_path[UFFS_MOUNT_PATH_MAX];
+	void * data;  /* when uffs use static buf, it will save ptr here */	
+};
+/* make sure the following struct var had been initilased to 0! */
+static struct _nand_dev nand_part[UFFS_DEVICE_MAX] = {0};
+
+static int uffs_result_to_dfs(int result)
+{
+	int status = -1;
+
+	switch (result)
+	{
+	case UENOERR:/** no error */
+		break;
+	case UEACCES:/** Tried to open read-only file for writing, or files sharing mode
+				   does not allow specified operations, or given path is directory */
+		status = -DFS_STATUS_EINVAL;
+		break;/* no suitable */
+	case UEEXIST:   /** _O_CREAT and _O_EXCL flags specified, but filename already exists */
+		status = -DFS_STATUS_EEXIST;
+		break;
+	case UEINVAL:  /** Invalid oflag or pmode argument */
+		status = -DFS_STATUS_EINVAL;
+		break;
+	case UEMFILE: /** No more file handles available(too many open files)  */
+		status = -1;
+		break;
+	case UENOENT: /** file or path not found */
+		status = -DFS_STATUS_ENOENT;
+		break;
+	case UETIME: /** can't set file time */
+		status = -1;
+		break;
+	case UEBADF: /** invalid file handle */
+		status = -DFS_STATUS_EBADF;
+		break;
+	case UENOMEM:/** no enough memory */
+		status = -DFS_STATUS_ENOMEM;
+		break;
+	case UEIOERR: /** I/O error from lower level flash operation */
+		status = -DFS_STATUS_EIO;
+		break;
+	case UENOTDIR: /** Not a directory */
+		status = -DFS_STATUS_ENOTDIR;
+		break;
+	case UEISDIR: /** Is a directory */
+		status = -DFS_STATUS_EISDIR;
+		break;
+	case UEUNKNOWN_ERR:
+	default:
+		status = -1;
+		break; /* unknown error! */
+	}
+
+	return status;
+}
+
+static URET _device_init(uffs_Device *dev)
+{
+	dev->attr->_private = NULL;	// hook nand_chip data structure to attr->_private
+	dev->ops = (struct uffs_FlashOpsSt *)&nand_ops;
+
+	return U_SUCC;
+}
+
+static URET _device_release(uffs_Device *dev)
+{
+	return U_SUCC;
+}
+
+static int init_uffs_fs(
+	struct _nand_dev * nand_part)
+{
+    uffs_MountTable * mtb;
+    struct rt_mtd_nand_device * nand;
+    struct uffs_StorageAttrSt * flash_storage;
+
+    mtb = &nand_part->mount_table;
+    nand = nand_part->dev;
+    flash_storage = &nand_part->storage;
+
+	/* setup nand storage attributes */
+	uffs_setup_storage(flash_storage, nand);
+
+	/* register mount table */
+	if(mtb->dev)
+	{
+		/* set memory allocator for uffs */
+#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
+		uffs_MemSetupSystemAllocator(&mtb->dev->mem);
+#endif
+		/* setup device init/release entry */
+		mtb->dev->Init = _device_init;
+		mtb->dev->Release = _device_release;
+		mtb->dev->attr = flash_storage;
+
+		uffs_RegisterMountTable(mtb);
+	}
+	/* mount uffs partion on nand device */
+	return uffs_mount_device(mtb) == U_SUCC ? 0 : -1;
+}
+
+static int dfs_uffs_mount(
+	struct dfs_filesystem* fs,
+    unsigned long rwflag,
+    const void* data)
+{
+	rt_base_t index;
+	uffs_MountTable * mount_part;
+	struct rt_mtd_nand_device * dev;
+	
+	RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX-1));
+	dev = RT_MTD_NAND_DEVICE(fs->dev_id);
+
+	/*1. find a empty entry in partition table */
+	for (index = 0; index < UFFS_DEVICE_MAX ; index ++)
+	{
+		if (nand_part[index].dev == RT_NULL)
+			break;
+	}
+	if (index == UFFS_DEVICE_MAX)
+		return -DFS_STATUS_ENOENT;
+
+	/*2. fill partition structure */
+	nand_part[index].dev = dev;
+
+	/* make a right mount path for uffs, end with '/' */
+	rt_snprintf(nand_part[index].mount_path, UFFS_MOUNT_PATH_MAX, "%s/", fs->path);
+	if (nand_part[index].mount_path[1] == '/')
+		nand_part[index].mount_path[1] = 0;
+
+	mount_part = &(nand_part[index].mount_table);
+	mount_part->mount	= nand_part[index].mount_path;
+	mount_part->dev = &(nand_part[index].uffs_dev);
+	rt_memset(mount_part->dev, 0, sizeof(uffs_Device));//in order to make uffs happy.
+	mount_part->dev->_private = dev;   /* save dev_id into uffs */
+	mount_part->start_block = dev->block_start;
+	mount_part->end_block = dev->block_end;
+	/*3. mount uffs */
+	if (init_uffs_fs(&nand_part[index]) < 0)
+	{
+		return uffs_result_to_dfs(uffs_get_error());
+	}
+	return 0;
+}
+
+static int dfs_uffs_unmount(struct dfs_filesystem* fs)
+{
+	rt_base_t index;
+	int result;
+
+	/* find the device index and then unmount it */
+	for (index = 0; index < UFFS_DEVICE_MAX; index++)
+	{
+		if (nand_part[index].dev == RT_MTD_NAND_DEVICE(fs->dev_id))
+		{
+			nand_part[index].dev = RT_NULL;
+			result = uffs_unmount_device(& nand_part[index].mount_table);
+			if (result != U_SUCC)
+				break;
+
+			result = uffs_UnRegisterMountTable(& nand_part[index].mount_table);
+			return (result == U_SUCC) ? DFS_STATUS_OK : -1;
+		}
+	}
+	return -DFS_STATUS_ENOENT;
+}
+
+static int dfs_uffs_mkfs(const char* device_name)
+{
+	rt_base_t index;
+	rt_uint32_t block;
+	struct rt_mtd_nand_device * mtd;
+
+	/*1. find the device index */
+	for (index = 0; index < UFFS_DEVICE_MAX; index++)
+	{
+		if (rt_strncmp(nand_part[index].dev->parent.parent.name,
+				       device_name, RT_NAME_MAX) == 0)
+			break;
+	}
+
+	if (index == UFFS_DEVICE_MAX)
+	{
+		/* can't find device driver */
+		rt_kprintf("can not find device driver: %s\n", device_name);
+		return -DFS_STATUS_ENOENT;
+	}
+
+	/*2. then unmount the partition */
+	uffs_mount_device(&nand_part[index].mount_table);
+	mtd = nand_part[index].dev;
+
+	/*3. erase all blocks on the partition */
+	block = mtd->block_start;
+	for (; block <= mtd->block_end; block++)
+	{
+		rt_mtd_nand_erase_block(mtd, block);
+		if (rt_mtd_nand_check_block(mtd, block) != RT_EOK)
+		{
+			rt_kprintf("found bad block %d\n", block);
+			rt_mtd_nand_mark_badblock(mtd, block);
+		}
+	}
+
+	/*4. remount it */
+	if (init_uffs_fs(&nand_part[index]) < 0)
+	{
+		return uffs_result_to_dfs(uffs_get_error());
+	}
+	return DFS_STATUS_OK;
+}
+
+static int dfs_uffs_statfs(struct dfs_filesystem* fs,
+                    struct statfs *buf)
+{
+	rt_base_t index;
+	struct rt_mtd_nand_device * mtd = RT_MTD_NAND_DEVICE(fs->dev_id);
+
+	RT_ASSERT(mtd != RT_NULL);
+
+	/* find the device index */
+	for (index = 0; index < UFFS_DEVICE_MAX; index++)
+	{
+		if (nand_part[index].dev == (void *)mtd)
+			break;
+	}
+	if (index == UFFS_DEVICE_MAX)
+		return -DFS_STATUS_ENOENT;
+	
+	buf->f_bsize = mtd->page_size;
+	buf->f_blocks = (mtd->block_size)/(mtd->page_size)*
+	                (mtd->block_start - mtd->block_end + 1);
+	buf->f_bfree = uffs_GetDeviceFree(&nand_part[index].uffs_dev) / mtd->page_size;
+	
+	return 0;
+}
+
+struct _uffs_data
+{
+	int fd; /* the handle of an open file/entry */
+	char * path; /* the path of the file/entry */
+};
+
+static int dfs_uffs_open(struct dfs_fd* file)
+{
+	int fd;
+	int oflag, mode;
+	struct _uffs_data * uffs_data;
+	char * file_path;
+
+	oflag = file->flags;
+	if (oflag & DFS_O_DIRECTORY)   /* operations about dir */
+	{
+		uffs_DIR * dir;
+
+		if (oflag & DFS_O_CREAT)   /* create a dir*/
+		{
+			if (uffs_mkdir(file->path) < 0)
+				return uffs_result_to_dfs(uffs_get_error());
+		}
+		/* open dir */
+		file_path = rt_malloc(FILE_PATH_MAX);
+		if(file_path == RT_NULL)
+			return -DFS_STATUS_ENOMEM;			
+
+		if (file->path[0] == '/' && !(file->path[1] == 0))
+			rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path);
+		else
+		{
+			file_path[0] = '/';
+			file_path[1] = 0;
+		}
+
+		dir = uffs_opendir(file_path);
+
+		if (dir == RT_NULL)
+		{
+			rt_free(file_path);			
+			return uffs_result_to_dfs(uffs_get_error());
+		}
+		/* save this pointer,will used by  dfs_uffs_getdents*/
+		file->data = dir;
+		rt_free(file_path);
+		return DFS_STATUS_OK;
+	}
+	/* regular file operations */
+	/* int uffs_open(const char *name, int oflag, ...); what is this?
+	 * uffs_open can open dir!!  **/
+	mode = 0;
+	if (oflag & DFS_O_RDONLY) mode |= UO_RDONLY;
+	if (oflag & DFS_O_WRONLY) mode |= UO_WRONLY;
+	if (oflag & DFS_O_RDWR)   mode |= UO_RDWR;
+	/* Opens the file, if it is existing. If not, a new file is created. */
+	if (oflag & DFS_O_CREAT) mode |= UO_CREATE;
+	/* Creates a new file. If the file is existing, it is truncated and overwritten. */
+	if (oflag & DFS_O_TRUNC) mode |= UO_TRUNC;
+	/* Creates a new file. The function fails if the file is already existing. */
+	if (oflag & DFS_O_EXCL) mode |= UO_EXCL;
+
+	fd = uffs_open(file->path, mode);
+	if (fd < 0)
+	{
+		return uffs_result_to_dfs(uffs_get_error());
+	}
+
+	uffs_data = rt_malloc(sizeof(struct _uffs_data));
+	if (uffs_data == RT_NULL)
+		return -DFS_STATUS_ENOMEM;
+
+	/* save file info */
+	uffs_data->fd = fd;
+	uffs_data->path = file->path;
+
+	/* save this pointer, it will be used when calling read()£¬write(),
+	 * flush(), seek(), and will be free when calling close()*/
+
+	file->data = uffs_data;
+	file->pos  = uffs_seek(fd, 0, USEEK_CUR);
+	file->size = uffs_seek(fd, 0, USEEK_END);
+	uffs_seek(fd, file->pos, USEEK_SET);
+
+	if (oflag & DFS_O_APPEND)
+	{
+		file->pos = uffs_seek(fd, 0, USEEK_END);
+	}
+	return 0;
+}
+
+static int dfs_uffs_close(struct dfs_fd* file)
+{
+	int oflag;
+	struct _uffs_data * uffs_data;
+
+	oflag = file->flags;
+	if (oflag & DFS_O_DIRECTORY)
+	{
+		/* operations about dir */
+		if (uffs_closedir((uffs_DIR *)(file->data)) < 0)
+			return uffs_result_to_dfs(uffs_get_error());
+
+		return 0;
+	}
+	/* regular file operations */
+	uffs_data = (struct _uffs_data *)(file->data);
+	RT_ASSERT(uffs_data != RT_NULL);
+
+	if (uffs_close(uffs_data->fd) == 0)
+	{
+		/* release memory */
+		rt_free(uffs_data);
+		return 0;
+	}
+
+	return uffs_result_to_dfs(uffs_get_error());
+}
+
+static int dfs_uffs_ioctl(struct dfs_fd * file, int cmd, void* args)
+{
+	return -DFS_STATUS_ENOSYS;
+}
+
+static int dfs_uffs_read(struct dfs_fd * file, void* buf, rt_size_t len)
+{
+	int fd;
+	struct _uffs_data * uffs_data;
+	int char_read;
+
+	uffs_data = (struct _uffs_data *)(file->data);
+	RT_ASSERT(uffs_data != RT_NULL);
+
+	fd = uffs_data->fd;
+	char_read = uffs_read(fd, buf, len);
+	if (char_read < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	/* update position */
+	file->pos = uffs_seek(fd, 0, USEEK_CUR);
+	return char_read;
+}
+
+static int dfs_uffs_write(struct dfs_fd* file,
+                   const void* buf,
+                   rt_size_t len)
+{
+	int fd;
+	struct _uffs_data * uffs_data;
+	int char_write;
+
+	uffs_data = (struct _uffs_data *)(file->data);
+	RT_ASSERT(uffs_data != RT_NULL);
+	fd = uffs_data->fd;
+
+	char_write = uffs_write(fd, buf, len);
+	if (char_write < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	/* update position */
+	file->pos = uffs_seek(fd, 0, USEEK_CUR);
+	return char_write;
+}
+
+static int dfs_uffs_flush(struct dfs_fd* file)
+{
+	int fd;
+	int result;
+	struct _uffs_data * uffs_data;
+
+	uffs_data = (struct _uffs_data *)(file->data);
+	RT_ASSERT(uffs_data != RT_NULL);
+	fd = uffs_data->fd;
+
+	result = uffs_flush(fd);
+	if (result < 0 )
+		return uffs_result_to_dfs(uffs_get_error());
+	return 0;
+}
+
+static int dfs_uffs_seek(struct dfs_fd* file,
+                  rt_off_t offset)
+{
+	int fd;
+	struct _uffs_data * uffs_data;
+	int result;
+
+	uffs_data = (struct _uffs_data *)(file->data);
+	RT_ASSERT(uffs_data != RT_NULL);
+	fd = uffs_data->fd;
+
+	/* set offset as current offset */
+	result = uffs_seek(fd, offset, USEEK_SET);
+	if (result < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+	return result;
+}
+
+/* return the size of struct dirent*/
+static int dfs_uffs_getdents(
+    struct dfs_fd* file,
+    struct dirent* dirp,
+    rt_uint32_t count)
+{
+	rt_uint32_t index;
+	char * file_path;
+	struct dirent* d;
+	uffs_DIR* dir;
+	struct uffs_dirent * uffs_d;
+	
+	dir = (uffs_DIR*)(file->data);
+	RT_ASSERT(dir != RT_NULL);
+	
+	/* round count, count is always 1 */
+	count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
+	if (count == 0) return -DFS_STATUS_EINVAL;
+
+	/* allocate file name */
+	file_path = rt_malloc(FILE_PATH_MAX);
+	if (file_path == RT_NULL)
+		return -DFS_STATUS_ENOMEM;
+		
+	index = 0;
+	/* usually, the while loop should only be looped only once! */
+	while (1)
+	{
+		struct uffs_stat s;
+		
+		d = dirp + index;
+
+		uffs_d = uffs_readdir(dir);
+		if (uffs_d == RT_NULL)
+		{
+			rt_free(file_path);
+			return (uffs_result_to_dfs(uffs_get_error()));
+		}
+
+		if (file->path[0] == '/' && !(file->path[1] == 0))
+			rt_snprintf(file_path, FILE_PATH_MAX, "%s/%s", file->path, uffs_d->d_name);
+		else
+			rt_strncpy(file_path, uffs_d->d_name, FILE_PATH_MAX);
+
+		uffs_stat(file_path, &s); 
+		switch(s.st_mode & US_IFMT)   /* file type mark */
+		{
+		case US_IFREG: /* directory */
+			d->d_type = DFS_DT_REG;
+			break;
+		case US_IFDIR: /* regular file */
+			d->d_type = DFS_DT_DIR;
+			break;
+		case US_IFLNK: /* symbolic link */
+		case US_IREAD: /* read permission */
+		case US_IWRITE:/* write permission */
+		default:
+			d->d_type = DFS_DT_UNKNOWN;
+			break;
+		}
+
+		/* write the rest args of struct dirent* dirp  */
+		d->d_namlen = rt_strlen(uffs_d->d_name);
+		d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
+		rt_strncpy(d->d_name, uffs_d->d_name, rt_strlen(uffs_d->d_name) + 1);
+
+		index ++;
+		if (index * sizeof(struct dirent) >= count)
+			break;
+	}
+	
+	/* free file name buf */
+	rt_free(file_path);
+	
+	if (index == 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	return index * sizeof(struct dirent);
+}
+
+static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path)
+{
+	int result;
+	struct uffs_stat s;
+
+	/* judge file type, dir is to be delete by uffs_rmdir, others by uffs_remove */
+	if (uffs_lstat(path, &s) < 0)
+	{
+		return uffs_result_to_dfs(uffs_get_error());
+	}
+
+	switch(s.st_mode & US_IFMT)
+	{
+	case US_IFREG:
+		result = uffs_remove(path);
+		break;
+	case US_IFDIR:
+		result = uffs_rmdir(path);
+		break;
+	default:
+		/* unknown file type */
+		return -1;
+	}
+	if (result < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	return 0;
+}
+
+static int dfs_uffs_rename(
+    struct dfs_filesystem* fs,
+    const char* oldpath,
+    const char* newpath)
+{
+	int result;
+	
+	result = uffs_rename(oldpath, newpath);
+	if (result < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	return 0;
+}
+
+static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
+{
+	int result;
+	struct uffs_stat s;
+	struct rt_mtd_nand_device * mtd;
+
+	result = uffs_stat(path, &s);
+	if (result < 0)
+		return uffs_result_to_dfs(uffs_get_error());
+
+	/* convert uffs stat to dfs stat structure */
+	/* FIXME, these field may not be the same */
+	st->st_dev  = 0;
+	st->st_mode = s.st_mode;
+	st->st_size = s.st_size;
+	st->st_mtime = s.st_mtime;
+
+	mtd = RT_MTD_NAND_DEVICE(fs->dev_id);
+	st->st_blksize = mtd->page_size;
+
+	return 0;
+}
+
+static const struct dfs_filesystem_operation dfs_uffs_ops =
+{
+	"uffs", /* file system type: uffs */
+#if RTTHREAD_VERSION >= 10100
+	DFS_FS_FLAG_FULLPATH,
+#else
+#error "uffs can only work with rtthread whose version should >= 1.01\n"
+#endif
+	dfs_uffs_mount,
+	dfs_uffs_unmount,
+	dfs_uffs_mkfs,
+	dfs_uffs_statfs,
+
+	dfs_uffs_open,
+	dfs_uffs_close,
+	dfs_uffs_ioctl,
+	dfs_uffs_read,
+	dfs_uffs_write,
+	dfs_uffs_flush,
+	dfs_uffs_seek,
+	dfs_uffs_getdents,
+	dfs_uffs_unlink,
+	dfs_uffs_stat,
+	dfs_uffs_rename,
+};
+
+int dfs_uffs_init(void)
+{
+	/* register uffs file system */
+	dfs_register(&dfs_uffs_ops);
+
+	if (uffs_InitObjectBuf() == U_SUCC)
+	{
+		if (uffs_DirEntryBufInit() == U_SUCC)
+		{
+			uffs_InitGlobalFsLock();
+			return RT_EOK;
+		}
+	}
+	return -RT_ERROR;
+}
+
+/* */
+#include "uffs/uffs_public.h"
+
+static URET uffs_mount_device(struct uffs_MountTableEntrySt *work)
+{
+	int dev_num = 0;
+
+	work->dev->par.start = work->start_block;
+	if (work->end_block < 0) {
+		work->dev->par.end =
+			work->dev->attr->total_blocks + work->end_block;
+	}
+	else {
+		work->dev->par.end = work->end_block;
+	}
+
+	if (work->dev->Init(work->dev) == U_FAIL) {
+		return U_FAIL;
+	}
+
+	if (uffs_InitDevice(work->dev) != U_SUCC) {
+		return U_FAIL;
+	}
+	work->dev->dev_num = dev_num++;
+
+	return U_SUCC;
+}
+
+static URET uffs_unmount_device(struct uffs_MountTableEntrySt *work)
+{
+	int result;
+
+	result = uffs_ReleaseDevice(work->dev);
+	work->dev->Release(work->dev);
+	return result;
+#if 0
+	if (uffs_ReleaseObjectBuf() == U_SUCC) {
+		if (uffs_DirEntryBufRelease() == U_SUCC) {
+			uffs_ReleaseGlobalFsLock();
+			return U_SUCC;
+		}
+	}
+
+	return U_FAIL;
+#endif
+}
+
+static URET uffs_UnRegisterMountTable(uffs_MountTable *mtab)
+{
+	struct uffs_MountTableEntrySt *tbl = uffs_GetMountTable();
+
+	if (tbl == NULL || mtab == NULL)
+		return U_FAIL;
+
+	while (tbl)
+	{
+		if (tbl == mtab)
+		{
+			tbl = mtab->next;
+			mtab->next = NULL;
+			return U_SUCC;
+		}
+		tbl = tbl->next;
+	}
+
+	return U_FAIL;
+}

+ 69 - 0
components/dfs/filesystems/uffs/dfs_uffs.h

@@ -0,0 +1,69 @@
+/*
+ * dfs_uffs.h
+ *
+ *  Created on: 2012-3-30
+ *      Author: prife
+ */
+
+#ifndef DFS_UFFS_H_
+#define DFS_UFFS_H_
+
+#include "uffs_config.h"
+#include "uffs/uffs_public.h"
+
+#define UFFS_BLOCK_MARK_SPARE_OFFSET  4    /* indicate block bad or good, offset in spare */
+
+#define RT_CONFIG_UFFS_ECC_MODE  UFFS_ECC_SOFT
+
+/* enable this ,you need provide a mark_badblock/check_block funciton */
+#define RT_UFFS_USE_CHECK_MARK_FUNCITON
+
+#if RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT      /* let uffs do soft ecc */
+
+#define RT_CONFIG_UFFS_LAYOUT    UFFS_LAYOUT_UFFS /* UFFS_LAYOUT_FLASH */
+#define RT_CONFIG_UFFS_ECC_SIZE  0                /* if 0, then uffs will caculate a proper ecc size */
+
+#elif RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO /* nand driver make ecc and do ecc correct */
+
+#define RT_CONFIG_UFFS_LAYOUT    UFFS_LAYOUT_FLASH
+#define RT_CONFIG_UFFS_ECC_SIZE  4                /* if 0, then uffs will caculate a proper ecc size */
+
+#elif RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_NONE
+
+#define RT_CONFIG_UFFS_LAYOUT    UFFS_LAYOUT_UFFS /* UFFS_LAYOUT_FLASH */
+#define RT_CONFIG_UFFS_ECC_SIZE  0                /* if 0, then uffs will caculate a proper ecc size */
+
+#else
+#error "uffs under rt-thread do not support this ECC mode"
+#endif
+
+#if (!CONFIG_USE_STATIC_MEMORY_ALLOCATOR)  && (CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR)
+#define RT_UFFS_MEMORY_ALLOCATOR  1  /* use system memory allocator */
+#elif (CONFIG_USE_STATIC_MEMORY_ALLOCATOR) && (!CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR)
+#define RT_UFFS_MEMORY_ALLOCATOR  0  /* use static memory allocator */
+#else
+#error "UFFS: CONFIG_USE_STATIC_MEMORY_ALLOCATOR ,CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR are invalid!"
+#endif
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0
+#error "dfs_uffs only support CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR"
+#endif
+
+#if defined(CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME)
+#error "dfs_uffs not support CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME"
+#endif
+
+#if (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO) && (RT_CONFIG_UFFS_LAYOUT != UFFS_LAYOUT_FLASH)
+#error "when use UFFS_ECC_HW_AUTO, you must use UFFS_LAYOUT_FLASH"
+
+#elif (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT) && (RT_CONFIG_UFFS_LAYOUT != UFFS_LAYOUT_UFFS)
+#warning "when use UFFS_ECC_SOFT, it is recommended to use UFFS_LAYOUT_UFFS"
+#endif
+
+extern const uffs_FlashOps nand_ops;
+
+extern void uffs_setup_storage(
+    struct uffs_StorageAttrSt *attr,
+    struct rt_mtd_nand_device * nand);
+
+#endif /* DFS_UFFS_H_ */

BIN
components/dfs/filesystems/uffs/doc/Understanding-UFFS.odp


BIN
components/dfs/filesystems/uffs/doc/Understanding-UFFS.pdf


BIN
components/dfs/filesystems/uffs/doc/uffs-serial-num-relationship.JPG


+ 637 - 0
components/dfs/filesystems/uffs/nand/k9f1g08_mtd.c

@@ -0,0 +1,637 @@
+/*
+ * File      : rtthread.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-10-13     prife        the first version 
+ * 2012-03-11     prife        use mtd device interface
+*/
+
+#include <rtdevice.h>
+#include <s3c24x0.h>
+
+/* nand flash commands. This appears to be generic across all NAND flash chips */
+#define CMD_READ			0x00	//  Read
+#define CMD_READ1			0x01	//  Read1
+#define CMD_READ2			0x50	//  Read2
+#define CMD_READ3			0x30	//  Read3
+#define CMD_READID			0x90	//  ReadID
+#define CMD_WRITE1			0x80	//  Write phase 1
+#define CMD_WRITE2			0x10	//  Write phase 2
+#define CMD_ERASE1			0x60	//  Erase phase 1
+#define CMD_ERASE2			0xd0	//  Erase phase 2
+#define CMD_STATUS			0x70	//  Status read
+#define CMD_RESET			0xff	//  Reset
+#define CMD_RANDOMREAD1     0x05    //  random read	 phase 1
+#define CMD_RANDOMREAD2     0xE0    //	random read	 phase 2
+#define CMD_RANDOMWRITE     0x85    //	random write phase 1
+
+#define NF_CMD(cmd)			{NFCMD  = (cmd); }
+#define NF_ADDR(addr)		{NFADDR = (addr); }	
+#define NF_CE_L()			{NFCONT &= ~(1<<1); }
+#define NF_CE_H()			{NFCONT |= (1<<1); }
+#define NF_RSTECC()			{NFCONT |= (1<<4); }
+#define NF_RDMECC()			(NFMECC0 )
+#define NF_RDSECC()			(NFSECC )
+#define NF_RDDATA()			(NFDATA)
+#define NF_RDDATA8()		(NFDATA8)
+#define NF_WRDATA(data)		{NFDATA = (data); }
+#define NF_WRDATA8(data)	{NFDATA8 = (data); } 
+#define NF_WAITRB()			{while(!(NFSTAT&(1<<0)));} 
+#define NF_CLEAR_RB()		{NFSTAT |= (1<<2); }
+#define NF_DETECT_RB()		{while(!(NFSTAT&(1<<2)));}
+#define NF_MECC_UNLOCK()	{NFCONT &= ~(1<<5); }
+#define NF_MECC_LOCK()		{NFCONT |= (1<<5); }
+#define NF_SECC_UNLOCK()	{NFCONT &= ~(1<<6); }
+#define NF_SECC_LOCK()		{NFCONT |= (1<<6); }
+
+/* HCLK=100Mhz, TACLS + TWRPH0 + TWRPH1 >= 50ns */
+#define TACLS				1       // 1-clock(0ns)
+#define TWRPH0				4       // 3-clock(25ns)
+#define TWRPH1				0       // 1-clock(10ns)
+
+/* status bit pattern */
+#define STATUS_READY        0x40    // ready
+#define STATUS_ERROR        0x01    // error
+#define	STATUS_ILLACC       0x08    // illegal access
+
+/* configurations */
+#define PAGE_DATA_SIZE                  2048
+#define BLOCK_MARK_SPARE_OFFSET         4
+//#define CONFIG_USE_HW_ECC
+static struct rt_mutex nand;
+
+#define BLOCK_MARK_OFFSET  (PAGE_DATA_SIZE + BLOCK_MARK_SPARE_OFFSET)
+/*
+ * In a page, data's ecc code is stored in spare area, from BYTE 0 to BYTEE 3.
+ * Block's status byte which indicate a block is bad or not is BYTE4.
+ */
+static void nand_hw_init(void)
+{
+	/* initialize GPIO£¬ nFWE£¬ALE£¬CLE£¬nFCE£¬nFRE */
+	GPACON |= (1<<17) | (1<<18) | (1<<19) | (1<<20) | (1<<22);
+
+	/* enable PCLK for nand controller */
+	CLKCON |= 1 << 4;
+
+	NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
+	NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
+	NFSTAT = 0;
+
+	/* reset nand flash */
+	NF_CE_L();
+	NF_CLEAR_RB();
+	NF_CMD(CMD_RESET);
+	NF_DETECT_RB();
+	NF_CE_H();
+}
+
+/*
+ *check the first byte in spare of the block's first page
+ *return
+ * good block,  RT_EOK
+ * bad  blcok, return -RT_ERROR
+ */
+static rt_err_t k9f1g08_mtd_check_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	rt_uint8_t status;
+	block =  block << 6;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+
+	NF_CMD(CMD_READ);
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+	NF_CMD(CMD_READ3);
+
+	NF_DETECT_RB();	 /* wait for ready bit */
+
+	status = NF_RDDATA8();
+	NF_CE_H();
+	/* TODO: more check about status */
+	return status == 0xFF ? RT_EOK : -RT_ERROR;
+
+#if 0
+	/* check the second page */
+	block ++;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+
+	NF_CMD(CMD_READ);
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+	NF_CMD(CMD_READ3);
+
+	NF_DETECT_RB();	 /* wait for ready bit */
+
+	status = NF_RDDATA8();
+	NF_CE_H();
+
+	return status == 0xFF ? RT_EOK : -RT_ERROR;
+#endif
+}
+
+static rt_err_t k9f1g08_mtd_mark_bad_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	/* get address of the fisrt page in the block */
+	rt_err_t result = RT_EOK;
+	block =  block << 6;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+	NF_CMD(CMD_WRITE1);
+
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+
+	/* write bad block mark in spare*/
+	NF_WRDATA8(0);
+
+	NF_CMD(CMD_WRITE2);
+ 	NF_DETECT_RB();	     /* wait for ready bit */
+
+	if ( NFSTAT & STATUS_ILLACC )
+	{
+		NFSTAT |= STATUS_ILLACC; /* write 1 to clear.*/
+        result = -RT_ERROR;
+	}
+	else
+	{
+		NF_CMD(CMD_STATUS);	/* get the status */
+
+		if (NF_RDDATA() &  STATUS_ERROR)
+			result = -RT_ERROR;
+	}
+
+	NF_CE_H(); /* disable chip select */
+    return result;
+}
+
+static rt_err_t k9f1g08_mtd_erase_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	/* 1 block = 64 page= 2^6*/
+    rt_err_t result = RT_EOK;
+	block <<= 6; /* get the first page's address in this block*/
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+	NF_CE_L();  /* enable chip */
+	NF_CLEAR_RB();
+	
+	NF_CMD(CMD_ERASE1);	/* erase one block 1st command */
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+//	NF_ADDR((block >> 16) & 0xff);
+	NF_CMD(CMD_ERASE2);	
+
+	NF_DETECT_RB(); /* wait for ready bit */
+
+	if ( NFSTAT & STATUS_ILLACC )
+	{
+		NFSTAT |= STATUS_ILLACC; /* write 1 to clear.*/
+        result = -RT_ERROR;
+	} else {
+		
+		NF_CMD(CMD_STATUS);	/* check status	*/
+
+		if (NF_RDDATA() & STATUS_ERROR) {
+			result = -RT_ERROR;
+		}
+	}
+
+	NF_CE_H();
+	rt_mutex_release(&nand);
+	return result;
+
+}
+
+/* return 0, ecc ok, 1, can be fixed , -1 can not be fixed */
+static rt_err_t k9f1g08_mtd_read(
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		rt_uint8_t * data, rt_uint32_t data_len, //may not always be 2048
+		rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+ 	rt_uint32_t mecc;
+	rt_uint32_t status;
+	rt_err_t result = RT_EOK;
+	
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_RSTECC();   /* reset ECC*/
+	NF_MECC_UNLOCK();/* unlock MECC */
+
+	NF_CE_L(); /* enable chip */
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		/* read page data area */
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* wait for ready bit */
+
+		/*TODO: use a more quick method */
+		for (i = 0; i < data_len; i++)
+			data[i] = NF_RDDATA8();
+
+		NF_MECC_LOCK();
+
+#if defined(CONFIG_USE_HW_ECC)
+		/* if read whole page data, then check ecc status */
+		if (data_len == PAGE_DATA_SIZE)
+		{
+			mecc = NF_RDDATA();
+
+			NFMECCD0 = ((mecc&0xff00)<<8)|(mecc&0xff);
+			NFMECCD1 = ((mecc&0xff000000)>>8)|((mecc&0xff0000)>>16);
+
+			/* check data ecc */
+			status = NFESTAT0 & 0x03;
+
+			if (status == 0x00)      /* no error */
+				result = RT_EOK;
+			else if (status == 0x01) /* error can be fixed */
+			{
+				//TODO add code to do ecc correct operation
+				result = -1;
+			}
+			else                    /* error can't be fixed */
+				result = -2;
+		}
+#endif
+
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		/* read page spare area */
+
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* wait for ready bit */
+		/*TODO: use a more quick method */
+		for (i = 0; i < spare_len; i++)
+			spare[i] = NF_RDDATA8();
+
+		NF_MECC_LOCK();
+
+		result = RT_EOK;
+	}
+	NF_CE_H();
+	rt_mutex_release(&nand);
+
+	/* TODO: more check about status */
+	return result;
+}
+
+static rt_err_t k9f1g08_mtd_write (
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		const rt_uint8_t * data, rt_uint32_t data_len,//will be 2048 always!
+		const rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+	rt_uint32_t mecc0;
+	rt_err_t result = RT_EOK;
+#if defined(CONFIG_USE_HW_ECC)
+	rt_uint8_t ecc_data[4];
+#endif
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_CE_L();       /* enable chip */
+
+	NF_RSTECC();
+	NF_MECC_UNLOCK();
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		RT_ASSERT(data_len == PAGE_DATA_SIZE);
+
+		NF_CLEAR_RB();
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<PAGE_DATA_SIZE; i++)
+			NF_WRDATA8(data[i]);
+
+		NF_MECC_LOCK();
+
+#if defined(CONFIG_USE_HW_ECC)
+		/* produce HARDWARE ECC */
+		mecc0=NFMECC0;
+		ecc_data[0]=(rt_uint8_t)(mecc0 & 0xff);
+		ecc_data[1]=(rt_uint8_t)((mecc0 >> 8) & 0xff);
+		ecc_data[2]=(rt_uint8_t)((mecc0 >> 16) & 0xff);
+		ecc_data[3]=(rt_uint8_t)((mecc0 >> 24) & 0xff);
+
+		/* write ecc to spare[0]..[3] */
+		for(i=0; i<4; i++)
+			NF_WRDATA8(ecc_data[i]);
+#endif
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();	 	/* wait for ready bit */
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_RDDATA() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		NF_CLEAR_RB();
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<spare_len; i++)
+			NF_WRDATA8(spare[i]);
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_RDDATA() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+__ret:
+	NF_CE_H(); /* disable chip */
+	rt_mutex_release(&nand);
+	return result;
+}
+
+static rt_err_t k9f1g08_read_id(
+		struct rt_mtd_nand_device * dev)
+{
+	return RT_EOK;
+}
+
+const static struct rt_mtd_nand_driver_ops k9f1g08_mtd_ops =
+{
+	k9f1g08_read_id,
+	k9f1g08_mtd_read,
+	k9f1g08_mtd_write,
+	k9f1g08_mtd_erase_block,
+	k9f1g08_mtd_check_block,
+	k9f1g08_mtd_mark_bad_block,
+};
+
+/* interface of nand and rt-thread device */
+static struct rt_mtd_nand_device nand_part[4];
+
+void k9f1g08_mtd_init()
+{
+	/* initialize nand controller of S3C2440 */
+	nand_hw_init();
+
+    /* initialize mutex */
+	if (rt_mutex_init(&nand, "nand", RT_IPC_FLAG_FIFO) != RT_EOK)
+	{
+		rt_kprintf("init nand lock mutex failed\n");
+	}
+	/* the first partition of nand */
+	nand_part[0].page_size = PAGE_DATA_SIZE;
+	nand_part[0].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[0].block_start = 0;
+	nand_part[0].block_end = 255;
+	nand_part[0].oob_size = 64;
+	nand_part[0].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand0", &nand_part[0]);
+
+	/* the second partition of nand */
+	nand_part[1].page_size = PAGE_DATA_SIZE;
+	nand_part[1].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[1].block_start = 256;
+	nand_part[1].block_end = 512-1;
+	nand_part[1].oob_size = 64;
+	nand_part[1].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand1", &nand_part[1]);
+
+	/* the third partition of nand */
+	nand_part[2].page_size = PAGE_DATA_SIZE;
+	nand_part[2].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[2].block_start = 512;
+	nand_part[2].block_end = 512+256-1;
+	nand_part[2].oob_size = 64;
+	nand_part[2].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand2", &nand_part[2]);
+
+	/* the 4th partition of nand */
+	nand_part[3].page_size = PAGE_DATA_SIZE;
+	nand_part[3].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[3].block_start = 512+256;
+	nand_part[3].block_end = 1024-1;
+	nand_part[3].oob_size = 64;
+	nand_part[3].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand3", &nand_part[3]);
+}
+
+#include "finsh.h"
+static char buf[PAGE_DATA_SIZE+64];
+static char spare[64];
+
+void nand_erase(int start, int end)
+{
+	int page;
+	for(; start <= end; start ++)
+	{
+		page = start * 64;
+		rt_memset(buf, 0, PAGE_DATA_SIZE);
+		rt_memset(spare, 0, 64);
+
+		k9f1g08_mtd_erase_block(RT_NULL, start);
+
+		k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+		if (spare[0] != 0xFF)
+		{
+			rt_kprintf("block %d is bad, mark it bad\n", start);
+
+			//rt_memset(spare, 0xFF, 64);
+			if (spare[4] == 0xFF)
+			{
+				spare[4] = 0x00;
+				k9f1g08_mtd_write(RT_NULL, page, RT_NULL, 0, spare, 64);
+			}
+		}
+	}
+}
+
+int nand_read(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+//	rt_memset(spare, 0, 64);
+
+//	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE+64, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+//		rt_kprintf("%02x ", spare[i]);
+		rt_kprintf("%02x ", buf[2048+i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_write(int page)
+{
+	int i;
+	rt_memset(buf, 0, PAGE_DATA_SIZE);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+		buf[i] = (i % 2) + i / 2;
+	return k9f1g08_mtd_write(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+}
+
+int nand_read2(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_memset(spare, 0, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, RT_NULL, 0, spare, 64);
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_read3(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+	rt_memset(spare, 0, 64);
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+
+int nand_check(int block)
+{
+	if ( k9f1g08_mtd_check_block(RT_NULL, block) != RT_EOK)
+		rt_kprintf("block %d is bad\n", block);
+	else
+		rt_kprintf("block %d is good\n", block);
+}
+
+int nand_mark(int block)
+{
+	return k9f1g08_mtd_mark_bad_block(RT_NULL, block);
+}
+FINSH_FUNCTION_EXPORT(nand_read, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read2, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read3, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_write, nand_write(1).);
+FINSH_FUNCTION_EXPORT(nand_check, nand_check(1).);
+FINSH_FUNCTION_EXPORT(nand_mark, nand_mark(1).);
+FINSH_FUNCTION_EXPORT(nand_erase, nand_erase(100, 200). erase block in nand);

+ 549 - 0
components/dfs/filesystems/uffs/nand/k9f1g08_mtd_ecc_hw.c

@@ -0,0 +1,549 @@
+/*
+ * File      : rtthread.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-10-13     prife        the first version 
+ * 2012-03-11     prife        use mtd device interface
+*/
+
+#include <rtdevice.h>
+#include <s3c24x0.h>
+//#include "nand.h"
+//  For flash chip that is bigger than 32 MB, we need to have 4 step address
+//  
+#define NFCONF_INIT			0xF830  // 512-byte 4 Step Address
+#define NEED_EXT_ADDR			1
+//#define NFCONF_INIT			0xA830  // 256-byte 4 Step Address
+//#define NEED_EXT_ADDR			0
+
+//#define NFCONF_INIT			0xF840
+//  NAND Flash Command. This appears to be generic across all NAND flash chips
+#define CMD_READ			0x00	//  Read
+#define CMD_READ1			0x01	//  Read1
+#define CMD_READ2			0x50	//  Read2
+#define CMD_READ3			0x30	//  Read3
+#define CMD_READID			0x90	//  ReadID
+#define CMD_WRITE1			0x80	//  Write phase 1
+#define CMD_WRITE2			0x10	//  Write phase 2
+#define CMD_ERASE1			0x60	//  Erase phase 1
+#define CMD_ERASE2			0xd0	//  Erase phase 2
+#define CMD_STATUS			0x70	//  Status read
+#define CMD_RESET			0xff	//  Reset
+#define CMD_RANDOMREAD1     0x05    //  random read	 phase 1
+#define CMD_RANDOMREAD2     0xE0    //	random read	 phase 2
+#define CMD_RANDOMWRITE     0x85    //	random write phase 1
+
+#define NF_CMD(cmd)			{NFCMD  = (cmd); }
+#define NF_ADDR(addr)		{NFADDR = (addr); }	
+#define NF_nFCE_L()			{NFCONT &= ~(1<<1); }
+#define NF_nFCE_H()			{NFCONT |= (1<<1); }
+#define NF_RSTECC()			{NFCONT |= (1<<4); }
+#define NF_RDMECC()			(NFMECC0 )
+#define NF_RDSECC()			(NFSECC )
+#define NF_RDDATA()			(NFDATA)
+#define NF_RDDATA8()		(NFDATA8)
+#define NF_WRDATA(data)		{NFDATA = (data); }
+#define NF_WRDATA8(data)	{NFDATA8 = (data); } 
+#define NF_WAITRB()			{while(!(NFSTAT&(1<<0)));} 
+#define NF_CLEAR_RB()		{NFSTAT |= (1<<2); }
+#define NF_DETECT_RB()		{while(!(NFSTAT&(1<<2)));}
+#define NF_MECC_UnLock()	{NFCONT &= ~(1<<5); }
+#define NF_MECC_Lock()		{NFCONT |= (1<<5); }
+#define NF_SECC_UnLock()	{NFCONT &= ~(1<<6); }
+#define NF_SECC_Lock()		{NFCONT |= (1<<6); }
+
+#define	RdNFDat8()			(NFDATA8)	//byte access
+#define	RdNFDat()			RdNFDat8()	//for 8 bit nand flash, use byte access
+#define	WrNFDat8(dat)		(NFDATA8 = (dat))	//byte access
+#define	WrNFDat(dat)		WrNFDat8()	//for 8 bit nand flash, use byte access
+
+#define NF_CE_L()			NF_nFCE_L()
+#define NF_CE_H()			NF_nFCE_H()
+#define NF_DATA_R()			NFDATA
+#define NF_ECC()			NFECC0
+
+
+// HCLK=100Mhz
+#define TACLS				1	// 1-clk(0ns) 
+#define TWRPH0				4	// 3-clk(25ns)
+#define TWRPH1				0	// 1-clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns
+
+//  Status bit pattern
+#define STATUS_READY            0x40        //  Ready
+#define STATUS_ERROR            0x01        //  Error
+#define	STATUS_ILLACC			0x08		//	Illigar Access
+//
+// ERROR_Xxx
+//
+#define ERR_SUCCESS						0
+#define ERR_DISK_OP_FAIL1				1
+#define ERR_DISK_OP_FAIL2				2
+#define ERR_INVALID_BOOT_SECTOR			3
+#define ERR_INVALID_LOAD_ADDR			4
+#define ERR_GEN_FAILURE					5
+#define ERR_INVALID_PARAMETER			6
+#define ERR_JUMP_FAILED					7
+#define ERR_INVALID_TOC					8
+#define ERR_INVALID_FILE_TYPE			9
+
+//#define NF_READID   1
+#define READ_SECTOR_INFO		
+
+
+#define NAND_BASE 0xB0E00000
+#define IOP_BASE  0xB1600000
+
+#define PAGE_DATA_SIZE  2048
+static struct rt_mutex nand;
+
+/*
+ * In a page, data's ecc code is stored in spare area, spare BYTE0 to BYTEE 3
+ * block's status byte which indicate a block is bad is BYTE4 in spare area
+ */
+static void nand_hw_init(void)
+{
+	/* Init GPIO£¬ nFWE£¬ALE£¬CLE£¬nFCE£¬nFRE */
+	GPACON |= (1<<17) | (1<<18) | (1<<19) | (1<<20) | (1<<22);
+
+	/* Enable PCLK into nand Controller */
+	CLKCON |= 1 << 4;
+
+	NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
+	NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
+	NFSTAT = 0;
+
+	/* reset nand flash */
+	NF_CE_L();
+	NF_CLEAR_RB();
+	NF_CMD(CMD_RESET);
+	NF_DETECT_RB();
+	NF_CE_H();
+}
+
+static rt_err_t k9f1g08_mtd_erase_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	/* 1 block = 64 page= 2^6*/
+    rt_err_t result = RT_EOK;
+	block <<= 6; /* get the first page's address in this block*/
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+	NF_nFCE_L();  /* enable chip */
+	NF_CLEAR_RB();
+	
+	NF_CMD(CMD_ERASE1);	/* Erase one block 1st command */
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+//	NF_ADDR((block >> 16) & 0xff);
+	NF_CMD(CMD_ERASE2);	
+
+	NF_DETECT_RB(); /* Wait for ready bit */
+
+	if ( NFSTAT & STATUS_ILLACC )
+	{
+		NFSTAT |= STATUS_ILLACC; /* Write 1 to clear.*/
+        result = -RT_ERROR;
+	} else {
+		
+		NF_CMD(CMD_STATUS);	/* Check the status	*/
+
+		if (NF_DATA_R() & STATUS_ERROR) {
+			result = -RT_ERROR;
+		}
+	}
+
+	NF_nFCE_H();
+	rt_mutex_release(&nand);
+	return result;
+/* TODO: more check about status */
+}
+
+/* return 0, ecc ok, 1, can be fixed , -1 can not be fixed */
+static rt_err_t k9f1g08_mtd_read(
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		rt_uint8_t * data, rt_uint32_t data_len, //may not always be 2048
+		rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+ 	rt_uint32_t mecc;
+	rt_uint32_t status;
+	rt_err_t result;
+	
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_RSTECC();   /* reset ECC*/
+	NF_MECC_UnLock();/* unlock MECC */
+
+	NF_nFCE_L(); /* enable chip */
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		/* read page data area */
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* Wait for RB	*/
+
+		/*TODO: use a more quick method */
+		for (i = 0; i < data_len; i++)
+			data[i] = NF_RDDATA8();
+
+		NF_MECC_Lock();
+
+		/* if read whole page data, then check ecc status */
+		if (data_len == PAGE_DATA_SIZE)
+		{
+			mecc = NF_RDDATA();
+
+			NFMECCD0 = ((mecc&0xff00)<<8)|(mecc&0xff);
+			NFMECCD1 = ((mecc&0xff000000)>>8)|((mecc&0xff0000)>>16);
+
+			/* check data ecc */
+			status = NFESTAT0 & 0x03;
+			if (status == 0x00)
+				result = RT_EOK; /* no error */
+			else if (status == 0x01)
+				result = -1;/* error can be fixed */
+			else
+				result = -2; /* erroe can't be fixed */
+		}
+		else
+			result = RT_EOK;
+
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		/* read page spare area */
+
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* Wait for RB	*/
+		/*TODO: use a more quick method */
+		for (i = 0; i < spare_len; i++)
+			spare[i] = NF_RDDATA8();
+
+		NF_MECC_Lock();
+
+		result = RT_EOK;
+	}
+	NF_nFCE_H();
+	rt_mutex_release(&nand);
+	return result;
+}
+
+static rt_err_t k9f1g08_mtd_write (
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		const rt_uint8_t * data, rt_uint32_t data_len,//will be 2048 always!
+		const rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+	rt_uint32_t mecc0;
+	rt_err_t result = RT_EOK;
+	rt_uint8_t ecc_data[4];
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_nFCE_L();       /* enable chip */
+
+	NF_RSTECC();
+	NF_MECC_UnLock();
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		RT_ASSERT(data_len == PAGE_DATA_SIZE);
+
+		NF_CLEAR_RB();     /* clear RB */
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<PAGE_DATA_SIZE; i++) //PAGE_DATA_SIZE
+			NF_WRDATA8(data[i]);
+
+		NF_MECC_Lock();
+
+		/* produce HARDWARE ECC */
+		mecc0=NFMECC0;
+		ecc_data[0]=(rt_uint8_t)(mecc0 & 0xff);
+		ecc_data[1]=(rt_uint8_t)((mecc0 >> 8) & 0xff);
+		ecc_data[2]=(rt_uint8_t)((mecc0 >> 16) & 0xff);
+		ecc_data[3]=(rt_uint8_t)((mecc0 >> 24) & 0xff);
+
+		/* write ecc to spare[0]..[3] */
+		for(i=0; i<4; i++)
+			NF_WRDATA8(ecc_data[i]);
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();	 	/* Wait for RB	*/
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_DATA_R() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		NF_CLEAR_RB();
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<spare_len; i++)
+			NF_WRDATA8(spare[i]);
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_DATA_R() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+__ret:
+	NF_nFCE_H(); /* disable chip */
+	rt_mutex_release(&nand);
+	return result;
+}
+
+static rt_err_t k9f1g08_read_id(
+		struct rt_mtd_nand_device * dev)
+{
+	return RT_EOK;
+}
+
+const static struct rt_mtd_nand_driver_ops k9f1g08_mtd_ops =
+{
+	k9f1g08_read_id,
+	k9f1g08_mtd_read,
+	k9f1g08_mtd_write,
+	k9f1g08_mtd_erase_block,
+};
+
+/* interface of nand and rt-thread device */
+static struct rt_mtd_nand_device nand_part[4];
+
+void k9f1g08_mtd_init()
+{
+	/* initialize nand controller of S3C2440 */
+	nand_hw_init();
+
+    /* initialize mutex */
+	if (rt_mutex_init(&nand, "nand", RT_IPC_FLAG_FIFO) != RT_EOK)
+	{
+		rt_kprintf("init nand lock mutex failed\n");
+	}
+	/* the first partition of nand */
+	nand_part[0].page_size = PAGE_DATA_SIZE;
+	nand_part[0].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[0].block_start = 0;
+	nand_part[0].block_end = 255;
+	nand_part[0].oob_size = 64;
+	nand_part[0].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand0", &nand_part[0]);
+
+	/* the second partition of nand */
+	nand_part[1].page_size = PAGE_DATA_SIZE;
+	nand_part[1].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[1].block_start = 256;
+	nand_part[1].block_end = 512-1;
+	nand_part[1].oob_size = 64;
+	nand_part[1].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand1", &nand_part[1]);
+
+	/* the third partition of nand */
+	nand_part[2].page_size = PAGE_DATA_SIZE;
+	nand_part[2].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[2].block_start = 512;
+	nand_part[2].block_end = 512+256-1;
+	nand_part[2].oob_size = 64;
+	nand_part[2].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand2", &nand_part[2]);
+
+	/* the 4th partition of nand */
+	nand_part[3].page_size = PAGE_DATA_SIZE;
+	nand_part[3].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[3].block_start = 512+256;
+	nand_part[3].block_end = 1024-1;
+	nand_part[3].oob_size = 64;
+	nand_part[3].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand3", &nand_part[3]);
+}
+
+#include "finsh.h"
+static char buf[PAGE_DATA_SIZE+64];
+static char spare[64];
+
+void nand_erase(int start, int end)
+{
+	int page;
+	for(; start <= end; start ++)
+	{
+		page = start * 64;
+		rt_memset(buf, 0, PAGE_DATA_SIZE);
+		rt_memset(spare, 0, 64);
+
+		k9f1g08_mtd_erase_block(RT_NULL, start);
+
+		k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+		if (spare[0] != 0xFF)
+		{
+			rt_kprintf("block %d is bad, mark it bad\n", start);
+
+			//rt_memset(spare, 0xFF, 64);
+			if (spare[4] == 0xFF)
+			{
+				spare[4] = 0x00;
+				k9f1g08_mtd_write(RT_NULL, page, RT_NULL, 0, spare, 64);
+			}
+		}
+	}
+}
+
+int nand_read(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+//	rt_memset(spare, 0, 64);
+
+//	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE+64, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+//		rt_kprintf("%02x ", spare[i]);
+		rt_kprintf("%02x ", buf[2048+i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_write(int page)
+{
+	int i;
+	rt_memset(buf, 0, PAGE_DATA_SIZE);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+		buf[i] = (i % 2) + i / 2;
+	return k9f1g08_mtd_write(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+}
+
+int nand_read2(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_memset(spare, 0, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, RT_NULL, 0, spare, 64);
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_read3(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+	rt_memset(spare, 0, 64);
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+FINSH_FUNCTION_EXPORT(nand_read, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read2, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read3, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_write, nand_write(1).);
+FINSH_FUNCTION_EXPORT(nand_erase, nand_erase(100, 200). erase block in nand);

+ 622 - 0
components/dfs/filesystems/uffs/nand/k9f1g08_mtd_ecc_soft.c

@@ -0,0 +1,622 @@
+/*
+ * File      : rtthread.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006-2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-10-13     prife        the first version 
+ * 2012-03-11     prife        use mtd device interface
+*/
+
+#include <rtdevice.h>
+#include <s3c24x0.h>
+
+/* nand flash commands. This appears to be generic across all NAND flash chips */
+#define CMD_READ			0x00	//  Read
+#define CMD_READ1			0x01	//  Read1
+#define CMD_READ2			0x50	//  Read2
+#define CMD_READ3			0x30	//  Read3
+#define CMD_READID			0x90	//  ReadID
+#define CMD_WRITE1			0x80	//  Write phase 1
+#define CMD_WRITE2			0x10	//  Write phase 2
+#define CMD_ERASE1			0x60	//  Erase phase 1
+#define CMD_ERASE2			0xd0	//  Erase phase 2
+#define CMD_STATUS			0x70	//  Status read
+#define CMD_RESET			0xff	//  Reset
+#define CMD_RANDOMREAD1     0x05    //  random read	 phase 1
+#define CMD_RANDOMREAD2     0xE0    //	random read	 phase 2
+#define CMD_RANDOMWRITE     0x85    //	random write phase 1
+
+#define NF_CMD(cmd)			{NFCMD  = (cmd); }
+#define NF_ADDR(addr)		{NFADDR = (addr); }	
+#define NF_CE_L()			{NFCONT &= ~(1<<1); }
+#define NF_CE_H()			{NFCONT |= (1<<1); }
+#define NF_RSTECC()			{NFCONT |= (1<<4); }
+#define NF_RDMECC()			(NFMECC0 )
+#define NF_RDSECC()			(NFSECC )
+#define NF_RDDATA()			(NFDATA)
+#define NF_RDDATA8()		(NFDATA8)
+#define NF_WRDATA(data)		{NFDATA = (data); }
+#define NF_WRDATA8(data)	{NFDATA8 = (data); } 
+#define NF_WAITRB()			{while(!(NFSTAT&(1<<0)));} 
+#define NF_CLEAR_RB()		{NFSTAT |= (1<<2); }
+#define NF_DETECT_RB()		{while(!(NFSTAT&(1<<2)));}
+#define NF_MECC_UNLOCK()	{NFCONT &= ~(1<<5); }
+#define NF_MECC_LOCK()		{NFCONT |= (1<<5); }
+#define NF_SECC_UNLOCK()	{NFCONT &= ~(1<<6); }
+#define NF_SECC_LOCK()		{NFCONT |= (1<<6); }
+
+/* HCLK=100Mhz, TACLS + TWRPH0 + TWRPH1 >= 50ns */
+#define TACLS				1       // 1-clock(0ns)
+#define TWRPH0				4       // 3-clock(25ns)
+#define TWRPH1				0       // 1-clock(10ns)
+
+/* status bit pattern */
+#define STATUS_READY        0x40    // ready
+#define STATUS_ERROR        0x01    // error
+#define	STATUS_ILLACC       0x08    // illegal access
+
+/* configurations */
+#define PAGE_DATA_SIZE                  2048
+#define BLOCK_MARK_SPARE_OFFSET         4
+//#define CONFIG_USE_HW_ECC
+static struct rt_mutex nand;
+
+#define BLOCK_MARK_OFFSET  (PAGE_DATA_SIZE + BLOCK_MARK_SPARE_OFFSET)
+/*
+ * In a page, data's ecc code is stored in spare area, from BYTE 0 to BYTEE 3.
+ * Block's status byte which indicate a block is bad or not is BYTE4.
+ */
+static void nand_hw_init(void)
+{
+	/* initialize GPIO£¬ nFWE£¬ALE£¬CLE£¬nFCE£¬nFRE */
+	GPACON |= (1<<17) | (1<<18) | (1<<19) | (1<<20) | (1<<22);
+
+	/* enable PCLK for nand controller */
+	CLKCON |= 1 << 4;
+
+	NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
+	NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
+	NFSTAT = 0;
+
+	/* reset nand flash */
+	NF_CE_L();
+	NF_CLEAR_RB();
+	NF_CMD(CMD_RESET);
+	NF_DETECT_RB();
+	NF_CE_H();
+}
+
+/*
+ *check the first byte in spare of the block's first page
+ *return
+ * good block,  RT_EOK
+ * bad  blcok, return -RT_ERROR
+ */
+static rt_err_t k9f1g08_mtd_check_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	rt_uint8_t status;
+	block =  block << 6;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+
+	NF_CMD(CMD_READ);
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+	NF_CMD(CMD_READ3);
+
+	NF_DETECT_RB();	 /* wait for ready bit */
+
+	status = NF_RDDATA8();
+	NF_CE_H();
+	/* TODO: more check about status */
+	return status == 0xFF ? RT_EOK : -RT_ERROR;
+
+#if 0
+	/* check the second page */
+	block ++;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+
+	NF_CMD(CMD_READ);
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+	NF_CMD(CMD_READ3);
+
+	NF_DETECT_RB();	 /* wait for ready bit */
+
+	status = NF_RDDATA8();
+	NF_CE_H();
+
+	return status == 0xFF ? RT_EOK : -RT_ERROR;
+#endif
+}
+
+static rt_err_t k9f1g08_mtd_mark_bad_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	/* get address of the fisrt page in the block */
+	block =  block << 6;
+	rt_err_t result = RT_EOK;
+
+	NF_CE_L();
+	NF_CLEAR_RB();
+	NF_CMD(CMD_WRITE1);
+
+	NF_ADDR(BLOCK_MARK_OFFSET);
+	NF_ADDR((BLOCK_MARK_OFFSET >> 8) & 0xff);
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+	NF_ADDR((block >>16) & 0xff);
+
+	/* write bad block mark in spare*/
+	NF_WRDATA8(0);
+
+	NF_CMD(CMD_WRITE2);
+ 	NF_DETECT_RB();	     /* wait for ready bit */
+
+	if ( NFSTAT & STATUS_ILLACC )
+	{
+		NFSTAT |= STATUS_ILLACC; /* write 1 to clear.*/
+        result = -RT_ERROR;
+	}
+	else
+	{
+		NF_CMD(CMD_STATUS);	/* get the status */
+
+		if (NF_RDDATA() &  STATUS_ERROR)
+			result = -RT_ERROR;
+	}
+
+	NF_CE_H(); /* disable chip select */
+    return result;
+}
+
+static rt_err_t k9f1g08_mtd_erase_block(
+		struct rt_mtd_nand_device* device,
+		rt_uint32_t block)
+{
+	/* 1 block = 64 page= 2^6*/
+    rt_err_t result = RT_EOK;
+	block <<= 6; /* get the first page's address in this block*/
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+	NF_CE_L();  /* enable chip */
+	NF_CLEAR_RB();
+	
+	NF_CMD(CMD_ERASE1);	/* erase one block 1st command */
+	NF_ADDR(block & 0xff);
+	NF_ADDR((block >> 8) & 0xff);
+//	NF_ADDR((block >> 16) & 0xff);
+	NF_CMD(CMD_ERASE2);	
+
+	NF_DETECT_RB(); /* wait for ready bit */
+
+	if ( NFSTAT & STATUS_ILLACC )
+	{
+		NFSTAT |= STATUS_ILLACC; /* write 1 to clear.*/
+        result = -RT_ERROR;
+	} else {
+		
+		NF_CMD(CMD_STATUS);	/* check status	*/
+
+		if (NF_RDDATA() & STATUS_ERROR) {
+			result = -RT_ERROR;
+		}
+	}
+
+	NF_CE_H();
+	rt_mutex_release(&nand);
+	return result;
+
+}
+
+/* return 0, ecc ok, 1, can be fixed , -1 can not be fixed */
+static rt_err_t k9f1g08_mtd_read(
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		rt_uint8_t * data, rt_uint32_t data_len, //may not always be 2048
+		rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+ 	rt_uint32_t mecc;
+	rt_uint32_t status;
+	rt_err_t result = RT_EOK;
+	
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_RSTECC();   /* reset ECC*/
+	NF_MECC_UNLOCK();/* unlock MECC */
+
+	NF_CE_L(); /* enable chip */
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		/* read page data area */
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* wait for ready bit */
+
+		/*TODO: use a more quick method */
+		for (i = 0; i < data_len; i++)
+			data[i] = NF_RDDATA8();
+
+		NF_MECC_LOCK();
+
+#if defined(CONFIG_USE_HW_ECC)
+		/* if read whole page data, then check ecc status */
+		if (data_len == PAGE_DATA_SIZE)
+		{
+			mecc = NF_RDDATA();
+
+			NFMECCD0 = ((mecc&0xff00)<<8)|(mecc&0xff);
+			NFMECCD1 = ((mecc&0xff000000)>>8)|((mecc&0xff0000)>>16);
+
+			/* check data ecc */
+			status = NFESTAT0 & 0x03;
+
+			if (status == 0x00)      /* no error */
+				result = RT_EOK;
+			else if (status == 0x01) /* error can be fixed */
+			{
+				//TODO add code to do ecc correct operation
+				result = -1;
+			}
+			else                    /* error can't be fixed */
+				result = -2;
+		}
+#endif
+
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		/* read page spare area */
+
+		NF_CLEAR_RB();
+
+		NF_CMD(CMD_READ);
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR((page) & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+		NF_CMD(CMD_READ3);
+
+		NF_DETECT_RB();/* wait for ready bit */
+		/*TODO: use a more quick method */
+		for (i = 0; i < spare_len; i++)
+			spare[i] = NF_RDDATA8();
+
+		NF_MECC_LOCK();
+
+		result = RT_EOK;
+	}
+	NF_CE_H();
+	rt_mutex_release(&nand);
+
+	/* TODO: more check about status */
+	return result;
+}
+
+static rt_err_t k9f1g08_mtd_write (
+		struct rt_mtd_nand_device * dev,
+		rt_off_t page,
+		const rt_uint8_t * data, rt_uint32_t data_len,//will be 2048 always!
+		const rt_uint8_t * spare, rt_uint32_t spare_len)
+{
+	rt_uint32_t i;
+	rt_uint32_t mecc0;
+	rt_err_t result = RT_EOK;
+#if defined(CONFIG_USE_HW_ECC)
+	rt_uint8_t ecc_data[4];
+#endif
+
+	rt_mutex_take(&nand, RT_WAITING_FOREVER);
+
+	NF_CE_L();       /* enable chip */
+
+	NF_RSTECC();
+	NF_MECC_UNLOCK();
+
+	if (data != RT_NULL && data_len != 0)
+	{
+		RT_ASSERT(data_len == PAGE_DATA_SIZE);
+
+		NF_CLEAR_RB();
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(0);
+		NF_ADDR(0);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<PAGE_DATA_SIZE; i++)
+			NF_WRDATA8(data[i]);
+
+		NF_MECC_LOCK();
+
+#if defined(CONFIG_USE_HW_ECC)
+		/* produce HARDWARE ECC */
+		mecc0=NFMECC0;
+		ecc_data[0]=(rt_uint8_t)(mecc0 & 0xff);
+		ecc_data[1]=(rt_uint8_t)((mecc0 >> 8) & 0xff);
+		ecc_data[2]=(rt_uint8_t)((mecc0 >> 16) & 0xff);
+		ecc_data[3]=(rt_uint8_t)((mecc0 >> 24) & 0xff);
+
+		/* write ecc to spare[0]..[3] */
+		for(i=0; i<4; i++)
+			NF_WRDATA8(ecc_data[i]);
+#endif
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();	 	/* wait for ready bit */
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_RDDATA() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+	if (spare != RT_NULL && spare_len != 0)
+	{
+		NF_CLEAR_RB();
+		NF_CMD(CMD_WRITE1);
+
+		NF_ADDR(PAGE_DATA_SIZE);
+		NF_ADDR((PAGE_DATA_SIZE >> 8) & 0xff);
+		NF_ADDR( page & 0xff);
+		NF_ADDR((page >> 8) & 0xff);
+//		NF_ADDR((page >> 16) & 0xff);
+
+		for(i=0; i<spare_len; i++)
+			NF_WRDATA8(spare[i]);
+
+		NF_CMD(CMD_WRITE2);
+		NF_DETECT_RB();
+		if (NFSTAT & STATUS_ILLACC)
+		{
+			NFSTAT |= STATUS_ILLACC;
+			result = -RT_ERROR;
+			goto __ret;
+		}
+		else
+		{
+			NF_CMD(CMD_STATUS);
+			if (NF_RDDATA() & STATUS_ERROR)
+			{
+				result = -RT_ERROR;
+				goto __ret;
+			}
+		}
+	}
+
+__ret:
+	NF_CE_H(); /* disable chip */
+	rt_mutex_release(&nand);
+	return result;
+}
+
+static rt_err_t k9f1g08_read_id(
+		struct rt_mtd_nand_device * dev)
+{
+	return RT_EOK;
+}
+
+const static struct rt_mtd_nand_driver_ops k9f1g08_mtd_ops =
+{
+	k9f1g08_read_id,
+	k9f1g08_mtd_read,
+	k9f1g08_mtd_write,
+	k9f1g08_mtd_erase_block,
+	k9f1g08_mtd_check_block,
+	k9f1g08_mtd_mark_bad_block,
+};
+
+/* interface of nand and rt-thread device */
+static struct rt_mtd_nand_device nand_part[4];
+
+void k9f1g08_mtd_init()
+{
+	/* initialize nand controller of S3C2440 */
+	nand_hw_init();
+
+    /* initialize mutex */
+	if (rt_mutex_init(&nand, "nand", RT_IPC_FLAG_FIFO) != RT_EOK)
+	{
+		rt_kprintf("init nand lock mutex failed\n");
+	}
+	/* the first partition of nand */
+	nand_part[0].page_size = PAGE_DATA_SIZE;
+	nand_part[0].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[0].block_start = 0;
+	nand_part[0].block_end = 255;
+	nand_part[0].oob_size = 64;
+	nand_part[0].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand0", &nand_part[0]);
+
+	/* the second partition of nand */
+	nand_part[1].page_size = PAGE_DATA_SIZE;
+	nand_part[1].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[1].block_start = 256;
+	nand_part[1].block_end = 512-1;
+	nand_part[1].oob_size = 64;
+	nand_part[1].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand1", &nand_part[1]);
+
+	/* the third partition of nand */
+	nand_part[2].page_size = PAGE_DATA_SIZE;
+	nand_part[2].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[2].block_start = 512;
+	nand_part[2].block_end = 512+256-1;
+	nand_part[2].oob_size = 64;
+	nand_part[2].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand2", &nand_part[2]);
+
+	/* the 4th partition of nand */
+	nand_part[3].page_size = PAGE_DATA_SIZE;
+	nand_part[3].block_size = PAGE_DATA_SIZE*64;//don't caculate oob size
+	nand_part[3].block_start = 512+256;
+	nand_part[3].block_end = 1024-1;
+	nand_part[3].oob_size = 64;
+	nand_part[3].ops = &k9f1g08_mtd_ops;
+	rt_mtd_nand_register_device("nand3", &nand_part[3]);
+}
+
+#include "finsh.h"
+static char buf[PAGE_DATA_SIZE+64];
+static char spare[64];
+
+void nand_erase(int start, int end)
+{
+	int page;
+	for(; start <= end; start ++)
+	{
+		page = start * 64;
+		rt_memset(buf, 0, PAGE_DATA_SIZE);
+		rt_memset(spare, 0, 64);
+
+		k9f1g08_mtd_erase_block(RT_NULL, start);
+
+		k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+		if (spare[0] != 0xFF)
+		{
+			rt_kprintf("block %d is bad, mark it bad\n", start);
+
+			//rt_memset(spare, 0xFF, 64);
+			if (spare[4] == 0xFF)
+			{
+				spare[4] = 0x00;
+				k9f1g08_mtd_write(RT_NULL, page, RT_NULL, 0, spare, 64);
+			}
+		}
+	}
+}
+
+int nand_read(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+//	rt_memset(spare, 0, 64);
+
+//	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE+64, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+//		rt_kprintf("%02x ", spare[i]);
+		rt_kprintf("%02x ", buf[2048+i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_write(int page)
+{
+	int i;
+	rt_memset(buf, 0, PAGE_DATA_SIZE);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+		buf[i] = (i % 2) + i / 2;
+	return k9f1g08_mtd_write(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+}
+
+int nand_read2(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, RT_NULL, 0);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_memset(spare, 0, 64);
+	res = k9f1g08_mtd_read(RT_NULL, page, RT_NULL, 0, spare, 64);
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+int nand_read3(int page)
+{
+	int i;
+	int res;
+	rt_memset(buf, 0, sizeof(buf));
+	rt_memset(spare, 0, 64);
+
+	res = k9f1g08_mtd_read(RT_NULL, page, buf, PAGE_DATA_SIZE, spare, 64);
+	rt_kprintf("block=%d, page=%d\n", page/64, page%64);
+	for(i=0; i<PAGE_DATA_SIZE; i++)
+	{
+		rt_kprintf("%02x ", buf[i]);
+		if((i+1)%16 == 0)
+			rt_kprintf("\n");
+	}
+
+	rt_kprintf("spare:\n");
+	for(i=0; i<64; i++)
+	{
+		rt_kprintf("%02x ", spare[i]);
+		if((i+1)%8 == 0)
+			rt_kprintf("\n");
+	}
+	return res;
+}
+FINSH_FUNCTION_EXPORT(nand_read, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read2, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_read3, nand_read(1).);
+FINSH_FUNCTION_EXPORT(nand_write, nand_write(1).);
+FINSH_FUNCTION_EXPORT(nand_erase, nand_erase(100, 200). erase block in nand);

+ 7 - 0
components/dfs/filesystems/uffs/src/CMakeLists.txt

@@ -0,0 +1,7 @@
+ADD_SUBDIRECTORY(emu)
+ADD_SUBDIRECTORY(uffs)
+ADD_SUBDIRECTORY(utils)
+ADD_SUBDIRECTORY(example)
+ADD_SUBDIRECTORY(platform)
+ADD_SUBDIRECTORY(test/api_test)
+ADD_SUBDIRECTORY(test/clients)

+ 24 - 0
components/dfs/filesystems/uffs/src/emu/CMakeLists.txt

@@ -0,0 +1,24 @@
+SET (libemu_SRCS 
+		cmdline.c
+		cmdline.h
+		helper_cmds.c
+		uffs_fileem.c
+		uffs_fileem_share.c
+		uffs_fileem_wrap.c
+		uffs_fileem_ecc_soft.c
+		uffs_fileem_ecc_hw.c
+		uffs_fileem_ecc_hw_auto.c
+		uffs_fileem.h
+		test_cmds.c
+	)
+
+IF (UNIX)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix)
+ENDIF()
+IF (WIN32)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32)
+ENDIF()
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/test/api_test)
+ADD_LIBRARY(emu STATIC ${libemu_SRCS} )
+

+ 643 - 0
components/dfs/filesystems/uffs/src/emu/cmdline.c

@@ -0,0 +1,643 @@
+/*
+This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+UFFS is free software; you can redistribute it and/or modify it under
+the GNU Library General Public License as published by the Free Software 
+Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+UFFS 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
+or GNU Library General Public License, as applicable, for more details.
+
+You should have received a copy of the GNU General Public License
+and GNU Library General Public License along with UFFS; if not, write
+to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA  02110-1301, USA.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered
+by the GNU General Public License. However the source code for this
+file must still be made available in accordance with section (3) of
+the GNU General Public License v2.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+
+/**
+* \file cmdline.c
+* \brief command line test interface
+* \author Ricky Zheng, created in 22th Feb, 2007
+*/
+
+#include <string.h>
+#include <stdio.h>
+//#include <conio.h>
+#include "uffs_config.h"
+#include "cmdline.h"
+#include "uffs/uffs_fs.h"
+
+#define PROMPT "UFFS>"
+
+#define PFX "cli : "
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+#define MAX_CLI_ARGS_BUF_LEN	120
+#define MAX_CLI_ARGS_NUM		20
+#define MAX_CLI_ENV_NUM			11		// '?', '0' - '9'
+
+
+struct cli_arg {
+	int argc;
+	char *argv[MAX_CLI_ARGS_NUM];
+	char _buf[MAX_CLI_ARGS_BUF_LEN];
+};
+
+static BOOL m_exit = FALSE;
+static BOOL m_abort = FALSE;
+static struct cli_commandset *m_cmdset_head = NULL;
+
+// Note: last command return code stored in env 0.
+static int m_cli_envs[MAX_CLI_ENV_NUM] = {0};	// cli environment variables
+
+static const struct cli_command * cli_find(const char *cmd);
+static int cmd_help(int argc, char *argv[]);
+
+
+#define FOR_EACH_CLI_CMD(set, cmd) \
+	for (set = m_cmdset_head; set && set->cmds; set = set->next) \
+		for (cmd = set->cmds; cmd && cmd->handler; cmd++)
+
+
+/*** filter out leading and tailing spaces, discard comments
+ * return pointer to start of new command line
+ */
+static char * cli_process_line(char *p)
+{
+	char *s;
+	char *x;
+
+	if (!p)
+		return NULL;
+
+	// skip leading spaces
+	while (p && (*p == ' ' || *p == '\t'))
+		p++;
+
+	for (s = x = p; *p; x++, p++) {
+		switch(*p) {
+		case '\\':
+			p++;
+			if (*p) {
+				switch(*p) {
+				case 'n':
+					*x = '\n';
+					break;
+				case 'r':
+					*x = '\r';
+					break;
+				case 't':
+					*x = '\t';
+					break;
+				case 'b':
+					*x = '\b';
+					break;
+				default:
+					if (*p >= '0' && *p <= '9')
+						*x = *p - '0';
+					else
+						*x = *p;
+					break;
+				}
+			}
+			break;
+		default:
+			if (*p == '\r' || *p == '\n' || *p == '#') *p = '\0';
+			*x = *p;
+			break;
+		}
+
+		if (*p == 0)
+			break;
+	}
+
+	// trim tailing spaces
+	p--;
+	while (p > s && (*p == ' ' || *p == '\t'))
+		*p-- = '\0';
+
+	return s;
+}
+
+static int cli_env_to_idx(char env)
+{
+	int idx = -1;
+
+	if (env >= '0' && env <= '9') {
+		idx = env - '0' + 1;
+	}
+	else if (env == '?') {
+		idx = 0;
+	}
+
+	return idx;
+}
+
+int cli_env_set(char env, int val)
+{
+	int idx = cli_env_to_idx(env);
+
+	if (idx >= 0) {
+		m_cli_envs[idx] = val;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+int cli_env_get(char env)
+{
+	int idx = cli_env_to_idx(env);
+
+	return idx >= 0 ? m_cli_envs[idx] : 0;
+}
+
+/** exec command <n> times:
+ *		exec <n> <cmd> [...]
+ */
+static int cmd_exec(int argc, char *argv[])
+{
+	int n = 0;
+	const struct cli_command *cmd;
+
+	CHK_ARGC(3, 0);
+
+	if (sscanf(argv[1], "%d", &n) != 1)
+		return CLI_INVALID_ARG;
+	if (n <= 0)
+		return CLI_INVALID_ARG;
+
+	cmd = cli_find(argv[2]);
+	if (cmd == NULL) {
+		MSG("Unknown command '%s'\n", argv[2]);
+		return -1;
+	}
+	else {
+		argv += 2;
+		while (n-- >= 0) {
+			if (cmd->handler(argc - 2, argv) != 0)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+/** 
+ * test expression
+ *	test <a> <op> <b>
+ * for example:
+ *	test 1 > 0    ==> return 0
+ *	test 1 <= 0   ==> return -1
+ */
+static int cmd_test(int argc, char *argv[])
+{
+	int a, b;
+	char *op;
+	BOOL tst = FALSE;
+
+	CHK_ARGC(4, 4);
+
+	if (sscanf(argv[1], "%d", &a) != 1 ||
+		sscanf(argv[3], "%d", &b) != 1)
+	{
+		return CLI_INVALID_ARG;
+	}
+
+	op = argv[2];
+	if (!strcmp(op, ">")) {
+		tst = (a > b);
+	}
+	else if (!strcmp(op, "<")) {
+		tst = (a < b);
+	}
+	else if (!strcmp(op, "==")) {
+		tst = (a == b);
+	}
+	else if (!strcmp(op, ">=")) {
+		tst = (a >= b);
+	}
+	else if (!strcmp(op, "<=")) {
+		tst = (a <= b);
+	}
+	else if (!strcmp(op, "!=")) {
+		tst = (a != b);
+	}
+	else {
+		return CLI_INVALID_ARG;
+	}
+	
+	return tst ? 0 : -1;
+}
+
+/** if last command failed (return != 0), run <cmd>
+ *    ! <cmd>
+ */
+static int cmd_failed(int argc, char *argv[])
+{
+	const struct cli_command *cmd;
+
+	CHK_ARGC(2, 0);
+
+	cmd = cli_find(argv[1]);
+	if (cmd == NULL) {
+		MSG("Unknown command '%s'\n", argv[1]);
+		return -1;
+	}
+	else {
+		argv++;
+		return (cli_env_get('?') == 0 ? 0 : cmd->handler(argc - 1, argv));
+	}
+}
+
+/** print messages
+ *		echo [<arg> ...]
+ */
+static int cmd_echo(int argc, char *argv[])
+{
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		MSG("%s%s", i > 1 ? " " : "", argv[i]);
+	}
+	MSG("\n");
+
+	return 0;
+}
+
+/** set cli environment variable
+ *		set <env> <value>
+ */
+static int cmd_set(int argc, char *argv[])
+{
+	int val;
+	int ret = -1;
+
+	CHK_ARGC(3, 0);
+
+	if (sscanf(argv[2], "%d", &val) == 1) {
+		ret = cli_env_set(argv[1][0], val);
+	}
+
+	return ret;
+}
+
+/** evaluation the expresstion, result to $1
+ *		evl <value> <op> <value>
+ */
+static int cmd_evl(int argc, char *argv[])
+{
+	int val1, val2, result = 0;
+	int ret = -1;
+
+	CHK_ARGC(4, 4);
+
+	if (sscanf(argv[1], "%d", &val1) == 1 &&
+		sscanf(argv[3], "%d", &val2) == 1) {
+		ret = 0;
+		switch(argv[2][0]) {
+			case '+':
+				result = val1 + val2;
+				break;
+			case '-':
+				result = val1 - val2;
+				break;
+			case '*':
+				result = val1 * val2;
+				break;
+			case '/':
+				if (val2 == 0)
+					ret = -1;
+				else
+					result = val1 / val2;
+				break;
+			case '%':
+				if (val2 == 0)
+					ret = -1;
+				else
+					result = val1 % val2;
+				break;
+			default:
+				ret = CLI_INVALID_ARG;
+				break;
+		}
+	}
+
+	if (ret == 0)
+		ret = cli_env_set('1', result);
+
+	return ret;
+}
+
+static int cmd_exit(int argc, char *argv[])
+{
+	m_exit = TRUE;
+	return 0;
+}
+
+/** Abort current script
+ *		abort [...]
+ */
+static int cmd_abort(int argc, char *argv[])
+{
+	if (argc > 1) {
+		cmd_echo(argc, argv);
+	}
+
+	m_abort = TRUE;
+
+	return 0;
+}
+
+/** run local file system's script
+ *		script <filename>
+ */
+static int cmd_script(int argc, char *argv[])
+{
+	char line_buf[256];
+	char *p;
+	FILE *fp;
+	const char *name;
+	int ret = 0;
+	static int stack = 0;
+
+	CHK_ARGC(2, 0);
+
+	if (stack++ == 0)
+		m_abort = FALSE;
+
+	name = argv[1];
+	fp = fopen(name, "r");
+
+	if (fp) {
+		memset(line_buf, 0, sizeof(line_buf));
+		while (!m_abort && fgets(line_buf, sizeof(line_buf) - 1, fp)) {
+			p = line_buf + sizeof(line_buf) - 1;
+			while (*p == 0 && p > line_buf)
+				p--;
+			while ((*p == '\r' || *p == '\n') && p > line_buf) {
+				*p-- = 0;
+			}
+			p = cli_process_line(line_buf);
+			if (*p)
+				ret = cli_interpret(p);
+			memset(line_buf, 0, sizeof(line_buf));
+		}
+		fclose(fp);
+	}
+	else {
+		MSG("Can't open host script file '%s' for read\n", name);
+		ret = -1;
+	}
+
+	stack--;
+
+	return ret;
+}
+
+
+
+static const struct cli_command default_cmds[] = 
+{
+	{ cmd_help,		"help|?",	"[<command>]",		"show commands or help on one command" },
+	{ cmd_exit,		"exit",		NULL,				"exit command line" },
+	{ cmd_exec,		"*",		"<n> <cmd> [...]>",	"run <cmd> <n> times" },
+	{ cmd_failed,	"!",		"<cmd> [...]",		"run <cmd> if last command failed" },
+	{ cmd_echo,		"echo",		"[...]",			"print messages" },
+	{ cmd_set,		"set",		"<env> <val>",		"set env variable" },
+	{ cmd_evl,		"evl",		"<val> <op> <val>",	"evaluation expresstion" },
+	{ cmd_test,		"test",		"<a> <op> <b>",		"test expression: <a> <op> <b>" },
+	{ cmd_script,   "script",   "<file>",           "run host script <file>" },
+	{ cmd_abort,	"abort",	NULL,				"abort from the running script" },
+	{ NULL, NULL, NULL, NULL }
+};
+
+static struct cli_commandset default_cmdset = {
+	default_cmds,
+};
+
+static BOOL match_cmd(const char *src, int start, int end, const char *des)
+{
+	while (src[start] == ' ' && start < end) 
+		start++;
+
+	while (src[end] == ' ' && start < end) 
+		end--;
+
+	if ((int)strlen(des) == (end - start + 1)) {
+		if (memcmp(src + start, des, end - start + 1) == 0) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static BOOL check_cmd(const char *cmds, const char *cmd)
+{
+	int start, end;
+
+	for (start = end = 0; cmds[end] != 0 && cmds[end] != '|'; end++);
+
+	while (end > start) {
+		if (match_cmd(cmds, start, end - 1, cmd) == TRUE) 
+			return TRUE;
+		if (cmds[end] == 0) 
+			break;
+		if (cmds[end] == '|') {
+			end++;
+			for (start = end; cmds[end] != 0 && cmds[end] != '|'; end++);
+		}
+	} 
+
+	return FALSE;
+}
+
+static const struct cli_command * cli_find(const char *cmd)
+{
+	struct cli_commandset *work;
+	const struct cli_command *s;
+
+	FOR_EACH_CLI_CMD(work, s) {
+		if (check_cmd(s->cmd, cmd) == TRUE)
+			return s;
+	}
+
+	return NULL;
+}
+
+static void show_cmd_usage(const struct cli_command *cmd)
+{
+	MSG("%s: %s\n", cmd->cmd, cmd->descr);
+	MSG("Usage: %s %s\n", cmd->cmd, cmd->args ? cmd->args : "");
+}
+
+static int cmd_help(int argc, char *argv[])
+{
+	const struct cli_command *cmd;
+	struct cli_commandset *cmdset;
+	int i, n;
+
+	if (argc < 2)  {
+		MSG("Available commands:\n");
+		n = 0;
+		FOR_EACH_CLI_CMD(cmdset, cmd) {
+			MSG("%s", cmd->cmd);
+			for (i = strlen(cmd->cmd); i%10; i++, MSG(" "));
+			if ((++n % 5) == 0) MSG("\n");
+		}
+		MSG("\n");
+	}
+	else {
+		cmd = cli_find(argv[1]);
+		if (cmd == NULL) {
+			MSG("No such command\n");
+			return -1;
+		}
+		else {
+			show_cmd_usage(cmd);
+		}
+	}
+
+	return 0;
+}
+
+static void cli_parse_args(const char *cmd, struct cli_arg *arg)
+{
+	char *p;
+	int val;
+
+	if (arg) {
+		arg->argc = 0;
+		if (cmd) {
+			p = arg->_buf;
+			while (*cmd && arg->argc < MAX_CLI_ARGS_NUM && (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN)) {
+				while(*cmd && (*cmd == ' ' || *cmd == '\t'))
+					cmd++;
+
+				arg->argv[arg->argc] = p;
+				while (*cmd && (*cmd != ' ' && *cmd != '\t') && (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN)) {
+					if (*cmd == '$') {
+						// command env replacement
+						cmd++;
+						val = cli_env_get(*cmd++);
+						if (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN - 12) {  // 12 is long enough for 32bit 'int'
+							p += sprintf(p, "%d", val & 0xFFFFFFFF);
+						}
+					}
+					else
+						*p++ = *cmd++;
+				}
+				*p++ = '\0';
+
+				if (*(arg->argv[arg->argc]) == '\0')
+					break;
+				arg->argc++;
+			}
+		}
+	}
+}
+
+int cli_interpret(const char *line)
+{
+	struct cli_arg arg = {0};
+	const struct cli_command *cmd;
+	int ret = -1;
+
+	cli_parse_args(line, &arg);
+
+	if (arg.argc > 0) {
+		cmd = cli_find(arg.argv[0]);
+		if (cmd == NULL) {
+			MSG("Unknown command '%s'\n", arg.argv[0]);
+		}
+		else {
+			ret = cmd->handler(arg.argc, arg.argv);
+			if (ret == CLI_INVALID_ARG) {
+				MSG("\n");
+				show_cmd_usage(cmd);
+			}
+		}
+	}
+
+	cli_env_set('?', ret);	// $? = last command return code
+
+	return ret;
+}
+
+void cli_add_commandset(struct cli_commandset *set)
+{
+	if (set) {
+		set->next = m_cmdset_head;
+		m_cmdset_head = set;
+	}
+}
+
+void cli_main_entry()
+{
+	char line[80];
+	int linelen = 0;
+	char *p;
+
+	MSG("$ ");
+	cli_add_commandset(&default_cmdset);
+
+	while (!m_exit) {
+		char ch;
+		if (linelen >= sizeof(line))
+			continue;
+		ch = getc(stdin);
+		switch (ch) {
+		case 8:
+		case 127:
+			if (linelen > 0) {
+				--linelen;
+				MSG("\x08 \x08");
+			}
+			break;
+
+		case '\r':
+		case '\n':
+			//MSG("\r\n");
+			if (linelen > 0) {
+				line[linelen] = 0;
+				p = cli_process_line(line);
+				if (*p)
+					cli_interpret(p);
+				linelen = 0;
+			}
+			MSG("$ ");
+			break;
+
+		case 21:
+			while (linelen > 0) {
+				--linelen;
+				MSG("\x08 \x08");
+			}
+			break;
+
+		default:
+			if (ch >= ' ' && ch < 127 && linelen < sizeof(line) - 1) {
+				line[linelen++] = ch;
+				//MSG("%c", ch);
+			}
+		}
+	}
+}

+ 83 - 0
components/dfs/filesystems/uffs/src/emu/cmdline.h

@@ -0,0 +1,83 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+
+#ifndef _UFFS_CLI_H_
+#define _UFFS_CLI_H_
+
+#ifndef BOOL
+#define BOOL int
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define CLI_INVALID_ARG			-100
+
+typedef int command_t(int argc, char *argv[]);
+
+struct cli_command {
+    command_t *handler;
+    const char *cmd;
+    const char *args;
+    const char *descr;
+};
+
+struct cli_commandset {
+	const struct cli_command *cmds;
+	struct cli_commandset *next;
+};
+
+void cli_add_commandset(struct cli_commandset *set);
+int cli_interpret(const char *line);
+int cli_env_get(char env);
+int cli_env_set(char env, int val);
+void cli_main_entry();
+
+#define u_assert(x) \
+	((x) ? TRUE : \
+			(uffs_PerrorRaw(UFFS_MSG_NORMAL, \
+				"Assert failed at %s:%s:%d: '%s' is not true.\n", \
+				__FILE__, __FUNCTION__, __LINE__, #x), FALSE))
+
+
+#define CHK_ARGC(min, max) \
+	if (argc < min || (max > 0 && argc > max)) \
+		return CLI_INVALID_ARG
+
+#endif
+
+

+ 657 - 0
components/dfs/filesystems/uffs/src/emu/helper_cmds.c

@@ -0,0 +1,657 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file helper_cmds.c
+ * \brief helper commands for test uffs
+ * \author Ricky Zheng
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_fs.h"
+#include "uffs/uffs_utils.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_mtb.h"
+#include "uffs/uffs_find.h"
+#include "cmdline.h"
+#include "uffs/uffs_fd.h"
+#include "uffs/uffs_mtb.h"
+#include "uffs_fileem.h"
+
+#define PFX "cmd : "
+
+#define MAX_PATH_LENGTH 128
+
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+/** format [<mount>] */
+static int cmd_format(int argc, char *argv[])
+{
+	URET ret;
+	const char *mount = "/";
+	uffs_Device *dev;
+	UBOOL force = U_FALSE;
+
+	if (argc > 1) {
+		mount = argv[1];
+		if (argc > 2 && strcmp(argv[2], "-f") == 0)
+			force = U_TRUE;
+	}
+	MSGLN("Formating %s ... ", mount);
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point.");
+		return -1;
+	}
+	else {
+		ret = uffs_FormatDevice(dev, force);
+		if (ret != U_SUCC) {
+			MSGLN("Format fail.");
+			return -1;
+		}
+		else {
+			MSGLN("Format succ.");
+		}
+		uffs_PutDevice(dev);
+	}
+
+	return 0;
+}
+
+/** mkf <file> */
+static int cmd_mkf(int argc, char *argv[])
+{
+	int fd;
+	const char *name;
+	int oflags = UO_RDWR | UO_CREATE;
+
+	CHK_ARGC(2, 2);
+
+	name = argv[1];
+	fd = uffs_open(name, oflags);
+	if (fd < 0) {
+		MSGLN("Create %s fail, err: %d", name, uffs_get_error());
+		return -1;
+	}
+	else {
+		MSGLN("Create %s succ.", name);
+		uffs_close(fd);
+	}
+	
+	return 0;
+}
+
+/** mkdir <dir> */
+static int cmd_mkdir(int argc, char *argv[])
+{
+	const char *name;
+
+	CHK_ARGC(2, 0);
+
+	name = argv[1];
+	
+	if (uffs_mkdir(name) < 0) {
+		MSGLN("Create %s fail, err: %d", name, uffs_get_error());
+		return -1;
+	}
+	else {
+		MSGLN("Create %s succ.", name);
+	}
+
+	return 0;
+}
+
+
+static int CountObjectUnder(const char *dir)
+{
+	int count = 0;
+	uffs_DIR *dirp;
+
+	dirp = uffs_opendir(dir);
+	if (dirp) {
+		while (uffs_readdir(dirp) != NULL)
+			count++;
+		uffs_closedir(dirp);
+	}
+	return count;
+}
+
+static int cmd_pwd(int argc, char *argv[])
+{
+	MSGLN("not supported.");
+	return 0;
+}
+
+static int cmd_cd(int argc, char *argv[])
+{
+	MSGLN("Not supported");
+	return 0;
+}
+
+/** ls [<dir>] */
+static int cmd_ls(int argc, char *argv[])
+{
+	uffs_DIR *dirp;
+	struct uffs_dirent *ent;
+	struct uffs_stat stat_buf;
+	int count = 0;
+	char buf[MAX_PATH_LENGTH+2];
+	const char *name = "/";
+	char *sub;
+	int ret = 0;
+
+	CHK_ARGC(1, 2);
+
+	if (argc > 1)
+		name = argv[1];
+
+	dirp = uffs_opendir(name);
+	if (dirp == NULL) {
+		MSGLN("Can't open '%s' for list", name);
+		ret = -1;
+	}
+	else {
+		MSG("------name-----------size---------serial-----" TENDSTR);
+		ent = uffs_readdir(dirp);
+		while (ent) {
+			MSG("%9s", ent->d_name);
+			strcpy(buf, name);
+			sub = buf;
+			if (name[strlen(name)-1] != '/')
+				sub = strcat(buf, "/");
+			sub = strcat(sub, ent->d_name);
+			if (ent->d_type & FILE_ATTR_DIR) {
+				sub = strcat(sub, "/");
+				MSG("/  \t<%8d>", CountObjectUnder(sub));
+			}
+			else {
+				uffs_stat(sub, &stat_buf);
+				MSG("   \t %8d ", stat_buf.st_size);
+			}
+			MSG("\t%6d" TENDSTR, ent->d_ino);
+			count++;
+			ent = uffs_readdir(dirp);
+		}
+		
+		uffs_closedir(dirp);
+
+		MSG("Total: %d objects." TENDSTR, count);
+	}
+
+	return ret;
+}
+
+/** rm <obj> */
+static int cmd_rm(int argc, char *argv[])
+{
+	const char *name = NULL;
+	int ret = 0;
+	struct uffs_stat st;
+
+	CHK_ARGC(2, 2);
+
+	name = argv[1];
+
+	ret = uffs_stat(name, &st);
+	if (ret < 0) {
+		MSGLN("Can't stat '%s'", name);
+		return ret;
+	}
+
+	if (st.st_mode & US_IFDIR) {
+		ret = uffs_rmdir(name);
+	}
+	else {
+		ret = uffs_remove(name);
+	}
+
+	if (ret == 0)
+		MSGLN("Delete '%s' succ.", name);
+	else
+		MSGLN("Delete '%s' fail!", name);
+
+	return ret;
+}
+
+/** ren|mv <old> <new> */
+static int cmd_ren(int argc, char *argv[])
+{
+	const char *oldname;
+	const char *newname;
+	int ret;
+
+	CHK_ARGC(3, 3);
+
+	oldname = argv[1];
+	newname = argv[2];
+
+	if ((ret = uffs_rename(oldname, newname)) == 0) {
+		MSGLN("Rename from '%s' to '%s' succ.", oldname, newname);
+	}
+	else {
+		MSGLN("Rename from '%s' to '%s' fail!", oldname, newname);
+	}
+
+	return ret;
+}
+
+static void dump_msg_to_stdout(struct uffs_DeviceSt *dev, const char *fmt, ...)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	va_list args;
+
+	va_start(args, fmt);
+	//vprintf(fmt, args);
+	if (emu && emu->dump_fp)
+		vfprintf(emu->dump_fp, fmt, args);
+	va_end(args);
+}
+
+/** dump [<mount>] */
+static int cmd_dump(int argc, char *argv[])
+{
+	uffs_Device *dev;
+	uffs_FileEmu *emu;
+	const char *mount = "/";
+	const char *dump_file = "dump.txt";
+
+	if (argc > 1) {
+		mount = argv[1];
+		if (argc > 2)
+			dump_file = argv[2];
+	}
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point %s", mount);
+		return -1;
+	}
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+	emu->dump_fp = fopen(dump_file, "w");
+
+	uffs_DumpDevice(dev, dump_msg_to_stdout);
+
+	if (emu->dump_fp)
+		fclose(emu->dump_fp);
+
+	uffs_PutDevice(dev);
+
+	return 0;
+}
+
+/** st [<mount>] */
+static int cmd_st(int argc, char *argv[])
+{
+	uffs_Device *dev;
+	const char *mount = "/";
+	uffs_FlashStat *s;
+	TreeNode *node;
+
+	if (argc > 1) {
+		mount = argv[1];
+	}
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point %s", mount);
+		return -1;
+	}
+
+	s = &(dev->st);
+
+	MSG("----------- basic info -----------" TENDSTR);
+	MSG("TreeNode size:         %d" TENDSTR, sizeof(TreeNode));
+	MSG("TagStore size:         %d" TENDSTR, sizeof(struct uffs_TagStoreSt));
+	MSG("MaxCachedBlockInfo:    %d" TENDSTR, dev->cfg.bc_caches);
+	MSG("MaxPageBuffers:        %d" TENDSTR, dev->cfg.page_buffers);
+	MSG("MaxDirtyPagesPerBlock: %d" TENDSTR, dev->cfg.dirty_pages);
+	MSG("MaxPathLength:         %d" TENDSTR, MAX_PATH_LENGTH);
+	MSG("MaxObjectHandles:      %d" TENDSTR, MAX_OBJECT_HANDLE);
+	MSG("FreeObjectHandles:     %d" TENDSTR, uffs_GetFreeObjectHandlers());
+	MSG("MaxDirHandles:         %d" TENDSTR, MAX_DIR_HANDLE);
+	MSG("FreeDirHandles:        %d" TENDSTR, uffs_PoolGetFreeCount(uffs_DirEntryBufGetPool()));
+
+	MSG("----------- statistics for '%s' -----------" TENDSTR, mount);
+	MSG("Device Ref:            %d" TENDSTR, dev->ref_count);
+	MSG("Block Erased:          %d" TENDSTR, s->block_erase_count);
+	MSG("Write Page:            %d" TENDSTR, s->page_write_count);
+	MSG("Write Spare:           %d" TENDSTR, s->spare_write_count);
+	MSG("Read Page:             %d" TENDSTR, s->page_read_count - s->page_header_read_count);
+	MSG("Read Header:           %d" TENDSTR, s->page_header_read_count);
+	MSG("Read Spare:            %d" TENDSTR, s->spare_read_count);
+	MSG("I/O Read:              %lu" TENDSTR, s->io_read);
+	MSG("I/O Write:             %lu" TENDSTR, s->io_write);
+
+	MSG("--------- partition info for '%s' ---------" TENDSTR, mount);
+	MSG("Space total:           %d" TENDSTR, uffs_GetDeviceTotal(dev));
+	MSG("Space used:            %d" TENDSTR, uffs_GetDeviceUsed(dev));
+	MSG("Space free:            %d" TENDSTR, uffs_GetDeviceFree(dev));
+	MSG("Page Size:             %d" TENDSTR, dev->attr->page_data_size);
+	MSG("Spare Size:            %d" TENDSTR, dev->attr->spare_size);
+	MSG("Pages Per Block:       %d" TENDSTR, dev->attr->pages_per_block);
+	MSG("Block size:            %d" TENDSTR, dev->attr->page_data_size * dev->attr->pages_per_block);
+	MSG("Total blocks:          %d of %d" TENDSTR, (dev->par.end - dev->par.start + 1), dev->attr->total_blocks);
+	if (dev->tree.bad) {
+		MSG("Bad blocks: ");
+		node = dev->tree.bad;
+		while(node) {
+			MSG("%d, ", node->u.list.block);
+			node = node->u.list.next;
+		}
+		MSG(TENDSTR);
+	}
+
+	uffs_PutDevice(dev);
+
+	return 0;
+
+}
+
+/** cp <src> <des> */
+static int cmd_cp(int argc, char *argv[])
+{
+	const char *src;
+	const char *des;
+	char buf[100];
+	int fd1 = -1, fd2 = -1;
+	int len;
+	BOOL src_local = FALSE, des_local = FALSE;
+	FILE *fp1 = NULL, *fp2 = NULL;
+	int ret = -1;
+
+	CHK_ARGC(3, 3);
+
+	src = argv[1];
+	des = argv[2];
+
+	if (memcmp(src, "::", 2) == 0) {
+		src += 2;
+		src_local = TRUE;
+	}
+	if (memcmp(des, "::", 2) == 0) {
+		des += 2;
+		des_local = TRUE;
+	}
+	
+	if (src_local) {
+		if ((fp1 = fopen(src, "rb")) == NULL) {
+			MSGLN("Can't open %s for copy.", src);
+			goto fail_ext;
+		}
+	}
+	else {
+		if ((fd1 = uffs_open(src, UO_RDONLY)) < 0) {
+			MSGLN("Can't open %s for copy.", src);
+			goto fail_ext;
+		}
+	}
+
+	if (des_local) {
+		if ((fp2 = fopen(des, "wb")) == NULL) {
+			MSGLN("Can't open %s for copy.", des);
+			goto fail_ext;
+		}
+	}
+	else {
+		if ((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0) {
+			MSGLN("Can't open %s for copy.", des);
+			goto fail_ext;
+		}
+	}
+
+	ret = 0;
+	while (	(src_local ? (feof(fp1) == 0) : (uffs_eof(fd1) == 0)) ) {
+		ret = -1;
+		if (src_local) {
+			len = fread(buf, 1, sizeof(buf), fp1);
+		}
+		else {
+			len = uffs_read(fd1, buf, sizeof(buf));
+		}
+		if (len == 0) {
+			ret = -1;
+			break;
+		}
+		if (len < 0) {
+			MSGLN("read file %s fail ?", src);
+			break;
+		}
+		if (des_local) {
+			if ((int)fwrite(buf, 1, len, fp2) != len) {
+				MSGLN("write file %s fail ? ", des);
+				break;
+			}
+		}
+		else {
+			if (uffs_write(fd2, buf, len) != len) {
+				MSGLN("write file %s fail ? ", des);
+				break;
+			}
+		}
+		ret = 0;
+	}
+
+fail_ext:
+	if (fd1 > 0)
+		uffs_close(fd1);
+	if (fd2 > 0)
+		uffs_close(fd2);
+	if (fp1) 
+		fclose(fp1);
+	if (fp2)
+		fclose(fp2);
+
+	return ret;
+}
+
+/** cat <file> [<offset>] [<size>] */
+static int cmd_cat(int argc, char *argv[])
+{
+	int fd;
+	const char *name = NULL;
+	char buf[100];
+	int start = 0, size = 0, printed = 0, n, len;
+	int ret = -1;
+
+	CHK_ARGC(2, 4);
+
+	name = argv[1];
+
+	if ((fd = uffs_open(name, UO_RDONLY)) < 0) {
+		MSGLN("Can't open %s", name);
+		goto fail;
+	}
+
+	if (argc > 2) {
+		start = strtol(argv[2], NULL, 10);
+		if (argc > 3) size = strtol(argv[3], NULL, 10);
+	}
+
+	if (start >= 0)
+		uffs_seek(fd, start, USEEK_SET);
+	else
+		uffs_seek(fd, -start, USEEK_END);
+
+	while (uffs_eof(fd) == 0) {
+		len = uffs_read(fd, buf, sizeof(buf) - 1);
+		if (len == 0) 
+			break;
+		if (len > 0) {
+			if (size == 0 || printed < size) {
+				n = (size == 0 ? len : (size - printed > len ? len : size - printed));
+				buf[n] = 0;
+				MSG("%s", buf);
+				printed += n;
+			}
+			else {
+				break;
+			}
+		}
+	}
+	MSG(TENDSTR);
+	uffs_close(fd);
+
+	ret = 0;
+fail:
+
+	return ret;
+}
+
+/** show mount table
+ *		mount
+ */
+static int cmd_mount(int argc, char *argv[])
+{
+	uffs_MountTable *tab = uffs_GetMountTable();
+
+	while (tab) {
+		MSGLN(" %s : (%d) ~ (%d)", tab->mount, tab->start_block, tab->end_block);
+		tab = tab->next;
+	}
+
+	return 0;
+}
+
+/** inspect buffers
+ *		inspb [<mount>]
+ */
+static int cmd_inspb(int argc, char *argv[])
+{
+	uffs_Device *dev;
+	const char *mount = "/";
+
+	CHK_ARGC(1, 2);
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point %s", mount);
+		return -1;
+	}
+	uffs_BufInspect(dev);
+	uffs_PutDevice(dev);
+
+	return 0;
+
+}
+
+/** print block wear-leveling information
+ *		wl [<mount>]
+ */
+static int cmd_wl(int argc, char *argv[])
+{
+	const char *mount = "/";
+	uffs_Device *dev;
+	struct uffs_PartitionSt *par;
+	uffs_FileEmu *emu;
+	int i, max;
+	u32 n;
+
+#define NUM_PER_LINE	10
+
+	CHK_ARGC(1, 2);
+
+	if (argc > 1) {
+		mount = argv[1];
+	}
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point %s", mount);
+		return -1;
+	}
+
+	par = &dev->par;
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+	max = -1;
+
+	for (i = 0; i < par->end - par->start; i++) {
+		if ((i % NUM_PER_LINE) == 0) {
+			MSG("%04d:", i + par->start);
+		}
+		n = i + par->start;
+		max = (max == -1 ? n :
+				(emu->em_monitor_block[n] > emu->em_monitor_block[max] ? n : max)
+			   );
+		MSG(" %4d", emu->em_monitor_block[n]);
+		if (uffs_TreeFindBadNodeByBlock(dev, n))
+			MSG("%c", 'x');
+		else if (uffs_TreeFindErasedNodeByBlock(dev, n))
+			MSG("%c", ' ');
+		else
+			MSG("%c", '.');
+		if (((i + 1) % NUM_PER_LINE) == 0)
+			MSG("\n");
+	}
+	MSG("\n");
+	MSG("Total blocks %d, peak erase count %d at block %d\n",
+		par->end - par->start, max == -1 ? 0 : emu->em_monitor_block[max], max);
+
+	uffs_PutDevice(dev);
+
+	return 0;
+}
+
+static const struct cli_command helper_cmds[] = 
+{
+    { cmd_format,	"format",		"[<mount>]",		"Format device" },
+    { cmd_mkf,		"mkfile",		"<name>",			"create a new file" },
+    { cmd_mkdir,	"mkdir",		"<name>",			"create a new directory" },
+    { cmd_rm,		"rm",			"<name>",			"delete file/directory" },
+    { cmd_ren,		"mv|ren",		"<old> <new>",		"rename file/directory" },
+    { cmd_ls,		"ls",			"<dir>",			"list dirs and files" },
+    { cmd_st,		"info|st",		"<mount>",			"show statistic infomation" },
+    { cmd_cp,		"cp",			"<src> <des>",		"copy files. the local file name start with '::'" },
+    { cmd_cat,		"cat",			"<name>",			"show file content" },
+    { cmd_pwd,		"pwd",			NULL,				"show current dir" },
+    { cmd_cd,		"cd",			"<path>",			"change current dir" },
+    { cmd_mount,	"mount",		NULL,				"list mounted file systems" },
+	{ cmd_dump,		"dump",			"[<mount>]",		"dump file system", },
+	{ cmd_wl,		"wl",			"[<mount>]",		"show block wear-leveling info", },
+	{ cmd_inspb,	"inspb",		"[<mount>]",		"inspect buffer", },
+    { NULL, NULL, NULL, NULL }
+};
+
+static struct cli_commandset helper_cmdset = {
+	helper_cmds,
+};
+
+struct cli_commandset * get_helper_cmds()
+{
+	return &helper_cmdset;
+};

+ 207 - 0
components/dfs/filesystems/uffs/src/emu/tags

@@ -0,0 +1,207 @@
+!_TAG_FILE_FORMAT	2	/extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED	1	/0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_PROGRAM_AUTHOR	Darren Hiebert	/dhiebert@users.sourceforge.net/
+!_TAG_PROGRAM_NAME	Exuberant Ctags	//
+!_TAG_PROGRAM_URL	http://ctags.sourceforge.net	/official site/
+!_TAG_PROGRAM_VERSION	5.8	//
+BOOL	cmdline.h	38;"	d
+CHK_ARGC	cmdline.h	77;"	d
+CLI_INVALID_ARG	cmdline.h	48;"	d
+CountObjectUnder	helper_cmds.c	/^static int CountObjectUnder(const char *dir)$/;"	f	file:
+DoTest2	test_cmds.c	/^static URET DoTest2(void)$/;"	f	file:
+FALSE	cmdline.h	45;"	d
+FILEEMU_ERASE_BAD_BLOCKS	uffs_fileem_wrap.c	66;"	d	file:
+FILEEMU_STOCK_BAD_BLOCKS	uffs_fileem_wrap.c	65;"	d	file:
+FILEEMU_WRITE_BIT_FLIP	uffs_fileem_wrap.c	69;"	d	file:
+FOR_EACH_CLI_CMD	cmdline.c	74;"	d	file:
+GBIT	test_cmds.c	657;"	d	file:
+InjectBitFlip	uffs_fileem_wrap.c	/^static void InjectBitFlip(uffs_Device *dev, u32 block, u32 page)$/;"	f	file:
+MAX_CLI_ARGS_BUF_LEN	cmdline.c	52;"	d	file:
+MAX_CLI_ARGS_NUM	cmdline.c	53;"	d	file:
+MAX_CLI_ENV_NUM	cmdline.c	54;"	d	file:
+MAX_PATH_LENGTH	helper_cmds.c	56;"	d	file:
+MAX_TEST_BUF_LEN	test_cmds.c	54;"	d	file:
+MSG	cmdline.c	50;"	d	file:
+MSG	helper_cmds.c	59;"	d	file:
+MSG	test_cmds.c	59;"	d	file:
+MSG	uffs_fileem.c	49;"	d	file:
+MSG	uffs_fileem_ecc_hw.c	53;"	d	file:
+MSG	uffs_fileem_ecc_hw_auto.c	64;"	d	file:
+MSG	uffs_fileem_ecc_soft.c	49;"	d	file:
+MSG	uffs_fileem_wrap.c	51;"	d	file:
+MSGLN	cmdline.c	49;"	d	file:
+MSGLN	helper_cmds.c	58;"	d	file:
+MSGLN	test_cmds.c	60;"	d	file:
+MSGLN	uffs_fileem.c	50;"	d	file:
+MSGLN	uffs_fileem_ecc_hw.c	54;"	d	file:
+MSGLN	uffs_fileem_ecc_hw_auto.c	65;"	d	file:
+MSGLN	uffs_fileem_ecc_soft.c	50;"	d	file:
+MSGLN	uffs_fileem_wrap.c	50;"	d	file:
+NUM_PER_LINE	helper_cmds.c	585;"	d	file:
+PAGE_DATA_SIZE	uffs_fileem_ecc_hw_auto.c	68;"	d	file:
+PAGE_DATA_WRITE_COUNT_LIMIT	uffs_fileem.h	54;"	d
+PAGE_FULL_SIZE	uffs_fileem_ecc_hw_auto.c	70;"	d	file:
+PAGE_SPARE_SIZE	uffs_fileem_ecc_hw_auto.c	69;"	d	file:
+PAGE_SPARE_WRITE_COUNT_LIMIT	uffs_fileem.h	55;"	d
+PFX	cmdline.c	48;"	d	file:
+PFX	helper_cmds.c	54;"	d	file:
+PFX	test_cmds.c	52;"	d	file:
+PFX	uffs_fileem.c	48;"	d	file:
+PFX	uffs_fileem_ecc_hw.c	52;"	d	file:
+PFX	uffs_fileem_ecc_hw_auto.c	63;"	d	file:
+PFX	uffs_fileem_ecc_soft.c	48;"	d	file:
+PFX	uffs_fileem_share.c	48;"	d	file:
+PFX	uffs_fileem_wrap.c	49;"	d	file:
+PROMPT	cmdline.c	46;"	d	file:
+RS_ECC_SIZE	uffs_fileem_ecc_hw_auto.c	67;"	d	file:
+SBIT	test_cmds.c	656;"	d	file:
+SEQ_INIT	test_cmds.c	56;"	d	file:
+SEQ_MOD_LEN	test_cmds.c	57;"	d	file:
+TRUE	cmdline.h	42;"	d
+UFFS_FEMU_ENABLE_INJECTION	uffs_fileem.h	48;"	d
+UFFS_FEMU_FILE_NAME	uffs_fileem.h	44;"	d
+UFFS_FEMU_MAX_BLOCKS	uffs_fileem.h	46;"	d
+_UFFS_CLI_H_	cmdline.h	35;"	d
+_UFFS_FILEEM_H_	uffs_fileem.h	40;"	d
+_buf	cmdline.c	/^	char _buf[MAX_CLI_ARGS_BUF_LEN];$/;"	m	struct:cli_arg	file:
+argc	cmdline.c	/^	int argc;$/;"	m	struct:cli_arg	file:
+args	cmdline.h	/^    const char *args;$/;"	m	struct:cli_command
+argv	cmdline.c	/^	char *argv[MAX_CLI_ARGS_NUM];$/;"	m	struct:cli_arg	file:
+block	uffs_fileem_wrap.c	/^	int block;$/;"	m	struct:uffs_FileEmuBitFlip	file:
+check_cmd	cmdline.c	/^static BOOL check_cmd(const char *cmds, const char *cmd)$/;"	f	file:
+check_entry_exist	test_cmds.c	/^static UBOOL check_entry_exist(const char *name)$/;"	f	file:
+cli_add_commandset	cmdline.c	/^void cli_add_commandset(struct cli_commandset *set)$/;"	f
+cli_arg	cmdline.c	/^struct cli_arg {$/;"	s	file:
+cli_command	cmdline.h	/^struct cli_command {$/;"	s
+cli_commandset	cmdline.h	/^struct cli_commandset {$/;"	s
+cli_env_get	cmdline.c	/^int cli_env_get(char env)$/;"	f
+cli_env_set	cmdline.c	/^int cli_env_set(char env, int val)$/;"	f
+cli_env_to_idx	cmdline.c	/^static int cli_env_to_idx(char env)$/;"	f	file:
+cli_find	cmdline.c	/^static const struct cli_command * cli_find(const char *cmd)$/;"	f	file:
+cli_interpret	cmdline.c	/^int cli_interpret(const char *line)$/;"	f
+cli_main_entry	cmdline.c	/^void cli_main_entry()$/;"	f
+cli_parse_args	cmdline.c	/^static void cli_parse_args(const char *cmd, struct cli_arg *arg)$/;"	f	file:
+cli_process_line	cmdline.c	/^static char * cli_process_line(char *p)$/;"	f	file:
+cmd	cmdline.h	/^    const char *cmd;$/;"	m	struct:cli_command
+cmd_TestFormat	test_cmds.c	/^static int cmd_TestFormat(int argc, char *argv[])$/;"	f	file:
+cmd_TestPageReadWrite	test_cmds.c	/^static int cmd_TestPageReadWrite(int argc, char *argv[])$/;"	f	file:
+cmd_TestPopulateFiles	test_cmds.c	/^static int cmd_TestPopulateFiles(int argc, char *argv[])$/;"	f	file:
+cmd_VerifyFile	test_cmds.c	/^static int cmd_VerifyFile(int argc, char *argv[])$/;"	f	file:
+cmd_abort	cmdline.c	/^static int cmd_abort(int argc, char *argv[])$/;"	f	file:
+cmd_apisrv	test_cmds.c	/^static int cmd_apisrv(int argc, char *argv[])$/;"	f	file:
+cmd_cat	helper_cmds.c	/^static int cmd_cat(int argc, char *argv[])$/;"	f	file:
+cmd_cd	helper_cmds.c	/^static int cmd_cd(int argc, char *argv[])$/;"	f	file:
+cmd_cp	helper_cmds.c	/^static int cmd_cp(int argc, char *argv[])$/;"	f	file:
+cmd_dump	helper_cmds.c	/^static int cmd_dump(int argc, char *argv[])$/;"	f	file:
+cmd_dump	test_cmds.c	/^static int cmd_dump(int argc, char *argv[])$/;"	f	file:
+cmd_echo	cmdline.c	/^static int cmd_echo(int argc, char *argv[])$/;"	f	file:
+cmd_evl	cmdline.c	/^static int cmd_evl(int argc, char *argv[])$/;"	f	file:
+cmd_exec	cmdline.c	/^static int cmd_exec(int argc, char *argv[])$/;"	f	file:
+cmd_exit	cmdline.c	/^static int cmd_exit(int argc, char *argv[])$/;"	f	file:
+cmd_failed	cmdline.c	/^static int cmd_failed(int argc, char *argv[])$/;"	f	file:
+cmd_format	helper_cmds.c	/^static int cmd_format(int argc, char *argv[])$/;"	f	file:
+cmd_help	cmdline.c	/^static int cmd_help(int argc, char *argv[])$/;"	f	file:
+cmd_inspb	helper_cmds.c	/^static int cmd_inspb(int argc, char *argv[])$/;"	f	file:
+cmd_ls	helper_cmds.c	/^static int cmd_ls(int argc, char *argv[])$/;"	f	file:
+cmd_mkdir	helper_cmds.c	/^static int cmd_mkdir(int argc, char *argv[])$/;"	f	file:
+cmd_mkf	helper_cmds.c	/^static int cmd_mkf(int argc, char *argv[])$/;"	f	file:
+cmd_mount	helper_cmds.c	/^static int cmd_mount(int argc, char *argv[])$/;"	f	file:
+cmd_pwd	helper_cmds.c	/^static int cmd_pwd(int argc, char *argv[])$/;"	f	file:
+cmd_ren	helper_cmds.c	/^static int cmd_ren(int argc, char *argv[])$/;"	f	file:
+cmd_rm	helper_cmds.c	/^static int cmd_rm(int argc, char *argv[])$/;"	f	file:
+cmd_script	cmdline.c	/^static int cmd_script(int argc, char *argv[])$/;"	f	file:
+cmd_set	cmdline.c	/^static int cmd_set(int argc, char *argv[])$/;"	f	file:
+cmd_st	helper_cmds.c	/^static int cmd_st(int argc, char *argv[])$/;"	f	file:
+cmd_t1	test_cmds.c	/^static int cmd_t1(int argc, char *argv[])$/;"	f	file:
+cmd_t2	test_cmds.c	/^static int cmd_t2(int argc, char *argv[])$/;"	f	file:
+cmd_t3	test_cmds.c	/^static int cmd_t3(int argc, char *argv[])$/;"	f	file:
+cmd_t4	test_cmds.c	/^static int cmd_t4(int argc, char *argv[])$/;"	f	file:
+cmd_t5	test_cmds.c	/^static int cmd_t5(int argc, char *argv[])$/;"	f	file:
+cmd_tcheck_seq	test_cmds.c	/^static int cmd_tcheck_seq(int argc, char *argv[])$/;"	f	file:
+cmd_tclose	test_cmds.c	/^static int cmd_tclose(int argc, char *argv[])$/;"	f	file:
+cmd_test	cmdline.c	/^static int cmd_test(int argc, char *argv[])$/;"	f	file:
+cmd_topen	test_cmds.c	/^static int cmd_topen(int argc, char *argv[])$/;"	f	file:
+cmd_tread	test_cmds.c	/^static int cmd_tread(int argc, char *argv[])$/;"	f	file:
+cmd_tseek	test_cmds.c	/^static int cmd_tseek(int argc, char *argv[])$/;"	f	file:
+cmd_twrite	test_cmds.c	/^static int cmd_twrite(int argc, char *argv[])$/;"	f	file:
+cmd_twrite_seq	test_cmds.c	/^static int cmd_twrite_seq(int argc, char *argv[])$/;"	f	file:
+cmd_wl	helper_cmds.c	/^static int cmd_wl(int argc, char *argv[])$/;"	f	file:
+cmds	cmdline.h	/^	const struct cli_command *cmds;$/;"	m	struct:cli_commandset	typeref:struct:cli_commandset::cli_command
+command_t	cmdline.h	/^typedef int command_t(int argc, char *argv[]);$/;"	t
+default_cmds	cmdline.c	/^static const struct cli_command default_cmds[] = $/;"	v	typeref:struct:cli_command	file:
+default_cmdset	cmdline.c	/^static struct cli_commandset default_cmdset = {$/;"	v	typeref:struct:cli_commandset	file:
+descr	cmdline.h	/^    const char *descr;$/;"	m	struct:cli_command
+do_dump_device	test_cmds.c	/^static void do_dump_device(uffs_Device *dev)$/;"	f	file:
+do_dump_page	test_cmds.c	/^static void do_dump_page(uffs_Device *dev, uffs_Buf *buf)$/;"	f	file:
+do_dump_tag	test_cmds.c	/^static void do_dump_tag(uffs_Device *dev, uffs_Tags *tag)$/;"	f	file:
+do_write_test_file	test_cmds.c	/^static URET do_write_test_file(int fd, int size)$/;"	f	file:
+drain_sdata	uffs_fileem_ecc_hw_auto.c	/^static void drain_sdata(u8 *data, int len)$/;"	f	file:
+dump_fp	uffs_fileem.h	/^	FILE *dump_fp;$/;"	m	struct:uffs_FileEmuSt
+dump_msg_to_stdout	helper_cmds.c	/^static void dump_msg_to_stdout(struct uffs_DeviceSt *dev, const char *fmt, ...)$/;"	f	file:
+em_monitor_block	uffs_fileem.h	/^	u32 *em_monitor_block;		\/\/ block erease monitor$/;"	m	struct:uffs_FileEmuSt
+em_monitor_page	uffs_fileem.h	/^	u8 *em_monitor_page;		\/\/ page write monitor$/;"	m	struct:uffs_FileEmuSt
+em_monitor_spare	uffs_fileem.h	/^	u8 * em_monitor_spare;		\/\/ spare write monitor$/;"	m	struct:uffs_FileEmuSt
+emu_filename	uffs_fileem.h	/^	const char *emu_filename;$/;"	m	struct:uffs_FileEmuSt
+feed_sdata	uffs_fileem_ecc_hw_auto.c	/^static void feed_sdata(const u8 *data, int len)$/;"	f	file:
+feed_sdata_constant	uffs_fileem_ecc_hw_auto.c	/^static void feed_sdata_constant(u8 val, int num)$/;"	f	file:
+femu_EraseBlock	uffs_fileem_share.c	/^int femu_EraseBlock(uffs_Device *dev, u32 blockNumber)$/;"	f
+femu_EraseBlock_wrap	uffs_fileem_wrap.c	/^static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber)$/;"	f	file:
+femu_GetPrivate	uffs_fileem.c	/^struct uffs_FileEmuSt *femu_GetPrivate()$/;"	f
+femu_GetStorage	uffs_fileem.c	/^struct uffs_StorageAttrSt * femu_GetStorage()$/;"	f
+femu_InitDevice	uffs_fileem.c	/^URET femu_InitDevice(uffs_Device *dev)$/;"	f
+femu_InitFlash	uffs_fileem_share.c	/^int femu_InitFlash(uffs_Device *dev)$/;"	f
+femu_InitFlash_wrap	uffs_fileem_wrap.c	/^static int femu_InitFlash_wrap(uffs_Device *dev)$/;"	f	file:
+femu_ReadPage	uffs_fileem_ecc_soft.c	/^static URET femu_ReadPage(uffs_Device *dev, u32 block, u32 page_num, u8 *data, int data_len, u8 *ecc,$/;"	f	file:
+femu_ReadPageWithLayout_wrap	uffs_fileem_wrap.c	/^static int femu_ReadPageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,$/;"	f	file:
+femu_ReadPage_wrap	uffs_fileem_wrap.c	/^static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,$/;"	f	file:
+femu_ReleaseDevice	uffs_fileem.c	/^URET femu_ReleaseDevice(uffs_Device *dev)$/;"	f
+femu_ReleaseFlash	uffs_fileem_share.c	/^int femu_ReleaseFlash(uffs_Device *dev)$/;"	f
+femu_WritePage	uffs_fileem_ecc_soft.c	/^static int femu_WritePage(uffs_Device *dev, u32 block, u32 page_num,$/;"	f	file:
+femu_WritePageWithLayout_wrap	uffs_fileem_wrap.c	/^static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc,$/;"	f	file:
+femu_WritePage_wrap	uffs_fileem_wrap.c	/^static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page,$/;"	f	file:
+femu_hw_ReadPageWithLayout	uffs_fileem_ecc_hw.c	/^static URET femu_hw_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,$/;"	f	file:
+femu_hw_WritePageWithLayout	uffs_fileem_ecc_hw.c	/^static int femu_hw_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,$/;"	f	file:
+femu_hw_auto_InitFlash	uffs_fileem_ecc_hw_auto.c	/^static int femu_hw_auto_InitFlash(uffs_Device *dev)$/;"	f	file:
+femu_hw_auto_ReadPageWithLayout	uffs_fileem_ecc_hw_auto.c	/^static URET femu_hw_auto_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,$/;"	f	file:
+femu_hw_auto_WritePageWithLayout	uffs_fileem_ecc_hw_auto.c	/^static int femu_hw_auto_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,$/;"	f	file:
+femu_setup_wrapper_functions	uffs_fileem_wrap.c	/^void femu_setup_wrapper_functions(uffs_Device *dev)$/;"	f
+fp	uffs_fileem.h	/^	FILE *fp;$/;"	m	struct:uffs_FileEmuSt
+g_femu_ops_ecc_hw	uffs_fileem_ecc_hw.c	/^uffs_FlashOps g_femu_ops_ecc_hw = {$/;"	v
+g_femu_ops_ecc_hw_auto	uffs_fileem_ecc_hw_auto.c	/^uffs_FlashOps g_femu_ops_ecc_hw_auto = {$/;"	v
+g_femu_ops_ecc_soft	uffs_fileem_ecc_soft.c	/^uffs_FlashOps g_femu_ops_ecc_soft = {$/;"	v
+g_femu_private	uffs_fileem.c	/^static struct uffs_FileEmuSt g_femu_private = {0};$/;"	v	typeref:struct:uffs_FileEmuSt	file:
+g_femu_storage	uffs_fileem.c	/^static struct uffs_StorageAttrSt g_femu_storage = {0};$/;"	v	typeref:struct:uffs_StorageAttrSt	file:
+g_page_buf	uffs_fileem_share.c	/^static u8 g_page_buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];$/;"	v	file:
+g_sdata_buf	uffs_fileem_ecc_hw_auto.c	/^static u8 g_sdata_buf[PAGE_FULL_SIZE];	\/\/ emulating LPC32x0's 528-bytes serial data buffer$/;"	v	file:
+g_sdata_buf_pointer	uffs_fileem_ecc_hw_auto.c	/^static int g_sdata_buf_pointer = 0;$/;"	v	file:
+get_helper_cmds	helper_cmds.c	/^struct cli_commandset * get_helper_cmds()$/;"	f
+get_test_cmds	test_cmds.c	/^struct cli_commandset * get_test_cmds()$/;"	f
+handler	cmdline.h	/^    command_t *handler;$/;"	m	struct:cli_command
+helper_cmds	helper_cmds.c	/^static const struct cli_command helper_cmds[] = $/;"	v	typeref:struct:cli_command	file:
+helper_cmdset	helper_cmds.c	/^static struct cli_commandset helper_cmdset = {$/;"	v	typeref:struct:cli_commandset	file:
+initCount	uffs_fileem.h	/^	int initCount;$/;"	m	struct:uffs_FileEmuSt
+load_sdata	uffs_fileem_ecc_hw_auto.c	/^static int load_sdata(uffs_Device *dev, int block, int page)$/;"	f	file:
+m_abort	cmdline.c	/^static BOOL m_abort = FALSE;$/;"	v	file:
+m_cli_envs	cmdline.c	/^static int m_cli_envs[MAX_CLI_ENV_NUM] = {0};	\/\/ cli environment variables$/;"	v	file:
+m_cmdset_head	cmdline.c	/^static struct cli_commandset *m_cmdset_head = NULL;$/;"	v	typeref:struct:cli_commandset	file:
+m_exit	cmdline.c	/^static BOOL m_exit = FALSE;$/;"	v	file:
+mask	uffs_fileem_wrap.c	/^	u8 mask;$/;"	m	struct:uffs_FileEmuBitFlip	file:
+match_cmd	cmdline.c	/^static BOOL match_cmd(const char *src, int start, int end, const char *des)$/;"	f	file:
+memcp_seq	test_cmds.c	/^static void memcp_seq(void *des, int size, int start_pos)$/;"	f	file:
+next	cmdline.h	/^	struct cli_commandset *next;$/;"	m	struct:cli_commandset	typeref:struct:cli_commandset::cli_commandset
+offset	uffs_fileem_wrap.c	/^	int offset;$/;"	m	struct:uffs_FileEmuBitFlip	file:
+ops_orig	uffs_fileem.h	/^	struct uffs_FlashOpsSt ops_orig;$/;"	m	struct:uffs_FileEmuSt	typeref:struct:uffs_FileEmuSt::uffs_FlashOpsSt
+page	uffs_fileem_wrap.c	/^	int page;$/;"	m	struct:uffs_FileEmuBitFlip	file:
+program_sdata	uffs_fileem_ecc_hw_auto.c	/^static int program_sdata(uffs_Device *dev, int block, int page)$/;"	f	file:
+show_cmd_usage	cmdline.c	/^static void show_cmd_usage(const struct cli_command *cmd)$/;"	f	file:
+start_sdata_access	uffs_fileem_ecc_hw_auto.c	/^static void start_sdata_access()$/;"	f	file:
+test_append_file	test_cmds.c	/^static URET test_append_file(const char *file_name, int size)$/;"	f	file:
+test_cmds	test_cmds.c	/^static const struct cli_command test_cmds[] = $/;"	v	typeref:struct:cli_command	file:
+test_cmdset	test_cmds.c	/^static struct cli_commandset test_cmdset = {$/;"	v	typeref:struct:cli_commandset	file:
+test_verify_file	test_cmds.c	/^static URET test_verify_file(const char *file_name, UBOOL noecc)$/;"	f	file:
+test_write_file	test_cmds.c	/^static URET test_write_file(const char *file_name, int pos, int size)$/;"	f	file:
+u_assert	cmdline.h	70;"	d
+uffs_FileEmu	uffs_fileem.h	/^} uffs_FileEmu;$/;"	t	typeref:struct:uffs_FileEmuSt
+uffs_FileEmuBitFlip	uffs_fileem_wrap.c	/^struct uffs_FileEmuBitFlip {$/;"	s	file:
+uffs_FileEmuSt	uffs_fileem.h	/^typedef struct uffs_FileEmuSt {$/;"	s
+wrap_inited	uffs_fileem.h	/^	UBOOL wrap_inited;$/;"	m	struct:uffs_FileEmuSt

+ 1186 - 0
components/dfs/filesystems/uffs/src/emu/test_cmds.c

@@ -0,0 +1,1186 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file test_cmds.c
+ * \brief commands for test uffs
+ * \author Ricky Zheng
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_fd.h"
+#include "uffs/uffs_utils.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_mtb.h"
+#include "uffs/uffs_find.h"
+#include "uffs/uffs_badblock.h"
+#include "cmdline.h"
+#include "api_test.h"
+
+#define PFX "test: "
+
+#define	MAX_TEST_BUF_LEN	8192
+
+#define SEQ_INIT	10
+#define SEQ_MOD_LEN	120
+
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+
+static void memcp_seq(void *des, int size, int start_pos)
+{
+	int i;
+	u8 *p = (u8 *)des;
+	
+	for (i = 0; i < size; i++, p++) {
+		*p = (start_pos + SEQ_INIT + i) % SEQ_MOD_LEN;
+	}
+}
+
+static UBOOL check_entry_exist(const char *name)
+{
+	struct uffs_stat sb;
+
+	return uffs_stat(name, &sb) < 0 ? U_FALSE : U_TRUE;
+}
+
+static URET do_write_test_file(int fd, int size)
+{
+	long pos;
+	unsigned char buf[100];
+	int len;
+
+	while (size > 0) {
+		pos = uffs_seek(fd, 0, USEEK_CUR);
+		len = (size > sizeof(buf) ? sizeof(buf) : size);
+		memcp_seq(buf, len, pos);
+		if (uffs_write(fd, buf, len) != len) {
+			MSGLN("Write file failed, size %d at %d", len, pos);
+			return U_FAIL;
+		}
+		size -= len;
+	}
+
+	return U_SUCC;
+}
+
+static URET test_write_file(const char *file_name, int pos, int size)
+{
+	int ret = U_FAIL;
+	int fd = -1;
+
+	if ((fd = uffs_open(file_name, UO_RDWR|UO_CREATE)) < 0) {
+		MSGLN("Can't open file %s for write.", file_name);
+		goto test_exit;
+	}
+
+	if (uffs_seek(fd, pos, USEEK_SET) != pos) {
+		MSGLN("Can't seek file %s at pos %d", file_name, pos);
+		goto test_failed;
+	}
+
+	if (do_write_test_file(fd, size) == U_FAIL) {
+		MSGLN("Write file %s failed.", file_name);
+		goto test_failed;
+	}
+	ret = U_SUCC;
+
+test_failed:
+	uffs_close(fd);
+
+test_exit:
+
+	return ret;
+}
+
+
+static URET test_verify_file(const char *file_name, UBOOL noecc)
+{
+	int fd;
+	int ret = U_FAIL;
+	unsigned char buf[100];
+	int i, pos, len;
+	u8 x;
+
+	if ((fd = uffs_open(file_name, (noecc ? UO_RDONLY|UO_NOECC : UO_RDONLY))) < 0) {
+		MSGLN("Can't open file %s for read.", file_name);
+		goto test_exit;
+	}
+
+	pos = 0;
+	while (!uffs_eof(fd)) {
+		len = uffs_read(fd, buf, sizeof(buf));
+		if (len <= 0)
+			goto test_failed;
+		for (i = 0; i < len; i++) {
+			x = (SEQ_INIT + pos + i) % SEQ_MOD_LEN;
+			if (buf[i] != x) {
+				MSGLN("Verify file %s failed at: %d, expect 0x%02x but got 0x%02x", file_name, pos + i, x, buf[i]);
+				goto test_failed;
+			}
+		}
+		pos += len;
+	}
+
+	if (pos != uffs_seek(fd, 0, USEEK_END)) {
+		MSGLN("Verify file %s failed. invalid file length.", file_name);
+		goto test_failed;
+	}
+
+	MSGLN("Verify file %s succ.", file_name);
+	ret = U_SUCC;
+
+test_failed:
+	uffs_close(fd);
+
+test_exit:
+
+	return ret;
+}
+
+static URET test_append_file(const char *file_name, int size)
+{
+	int ret = U_FAIL;
+	int fd = -1;
+
+	if ((fd = uffs_open(file_name, UO_RDWR|UO_APPEND|UO_CREATE)) < 0) {
+		MSGLN("Can't open file %s for append.", file_name);
+		goto test_exit;
+	}
+
+	uffs_seek(fd, 0, USEEK_END);
+
+	if (do_write_test_file(fd, size) == U_FAIL) {
+		MSGLN("Write file %s failed.", file_name);
+		goto test_failed;
+	}
+	ret = U_SUCC;
+
+test_failed:
+	uffs_close(fd);
+
+test_exit:
+
+	return ret;
+}
+
+
+/* test create file, write file and read back */
+static int cmd_t1(int argc, char *argv[])
+{
+	int fd;
+	URET ret;
+	char buf[100];
+	const char *name;
+
+	if (argc < 2) {
+		return CLI_INVALID_ARG;
+	}
+
+	name = argv[1];
+
+	fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC);
+	if (fd < 0) {
+		MSGLN("Can't open %s", name);
+		goto fail;
+	}
+
+	sprintf(buf, "123456789ABCDEF");
+	ret = uffs_write(fd, buf, strlen(buf));
+	MSGLN("write %d bytes to file, content: %s", ret, buf);
+
+	ret = uffs_seek(fd, 3, USEEK_SET);
+	MSGLN("new file position: %d", ret);
+
+	memset(buf, 0, sizeof(buf));
+	ret = uffs_read(fd, buf, 5);
+	MSGLN("read %d bytes, content: %s", ret, buf);
+
+	uffs_close(fd);
+
+	return 0;
+fail:
+
+	return -1;
+}
+
+
+static URET DoTest2(void)
+{
+	int fd = -1;
+	URET ret = U_FAIL;
+	char buf[100], buf_1[100];
+
+	fd = uffs_open("/abc/", UO_RDWR|UO_DIR);
+	if (fd < 0) {
+		MSGLN("Can't open dir abc, err: %d", uffs_get_error());
+		MSGLN("Try to create a new one...");
+		fd = uffs_open("/abc/", UO_RDWR|UO_CREATE|UO_DIR);
+		if (fd < 0) {
+			MSGLN("Can't create new dir /abc/");
+			goto exit_test;
+		}
+		else {
+			uffs_close(fd);
+		}
+	}
+	else {
+		uffs_close(fd);
+	}
+	
+	fd = uffs_open("/abc/test.txt", UO_RDWR|UO_CREATE);
+	if (fd < 0) {
+		MSGLN("Can't open /abc/test.txt");
+		goto exit_test;
+	}
+
+	sprintf(buf, "123456789ABCDEF");
+	ret = uffs_write(fd, buf, strlen(buf));
+	MSGLN("write %d bytes to file, content: %s", ret, buf);
+
+	ret = uffs_seek(fd, 3, USEEK_SET);
+	MSGLN("new file position: %d", ret);
+
+	memset(buf_1, 0, sizeof(buf_1));
+	ret = uffs_read(fd, buf_1, 5);
+	MSGLN("read %d bytes, content: %s", ret, buf_1);
+
+	if (memcmp(buf + 3, buf_1, 5) != 0) {
+		ret = U_FAIL;
+	}
+	else {
+		ret = U_SUCC;
+	}
+
+	uffs_close(fd);
+
+exit_test:
+
+	return ret;
+}
+
+
+static int cmd_t2(int argc, char *argv[])
+{
+	URET ret;
+	MSGLN("Test return: %s !", (ret = DoTest2()) == U_SUCC ? "succ" : "failed");
+
+	return (ret == U_SUCC) ? 0 : -1;
+}
+
+
+static int cmd_VerifyFile(int argc, char *argv[])
+{
+	const char *name;
+	UBOOL noecc = U_FALSE;
+
+	if (argc < 2) {
+		return CLI_INVALID_ARG;
+	}
+
+	name = argv[1];
+	if (argc > 2 && strcmp(argv[2], "noecc") == 0) {
+		noecc = U_TRUE;
+	}
+
+	MSGLN("Check file %s ... ", name);
+	if (test_verify_file(name, noecc) != U_SUCC) {
+		MSGLN("Verify file %s failed.", name);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Test file append and 'random' write */
+static int cmd_t3(int argc, char *argv[])
+{
+	const char *name;
+	int i;
+	UBOOL noecc = U_FALSE;
+	int write_test_seq[] = { 20, 10, 500, 40, 1140, 900, 329, 4560, 352, 1100 };
+
+	if (argc < 2) {
+		return CLI_INVALID_ARG;
+	}
+
+	name = argv[1];
+	if (argv[2] && strcmp(argv[2], "noecc") == 0) {
+		noecc = U_TRUE;
+	}
+
+	if (check_entry_exist(name)) {
+		MSGLN("Check file %s ... ", name);
+		if (test_verify_file(name, noecc) != U_SUCC) {
+			MSGLN("Verify file %s failed.", name);
+			return -1;
+		}
+	}
+
+	MSGLN("Test append file %s ...", name);
+	for (i = 1; i < 500; i += 29) {
+		if (test_append_file(name, i) != U_SUCC) {
+			MSGLN("Append file %s test failed at %d !", name, i);
+			return -1;
+		}
+	}
+
+	MSGLN("Check file %s ... ", name);
+	if (test_verify_file(name, noecc) != U_SUCC) {
+		MSGLN("Verify file %s failed.", name);
+		return -1;
+	}
+
+	MSGLN("Test write file ...");
+	for (i = 0; i < sizeof(write_test_seq) / sizeof(int) - 1; i++) {
+		if (test_write_file(name, write_test_seq[i], write_test_seq[i+1]) != U_SUCC) {
+			MSGLN("Test write file failed !");
+			return -1;
+		}
+	}
+
+	MSGLN("Check file %s ... ", name);
+	if (test_verify_file(name, noecc) != U_SUCC) {
+		MSGLN("Verify file %s failed.", name);
+		return -1;
+	}
+
+	MSGLN("Test succ !");
+
+	return 0;
+}
+
+/* open two files and test write */
+static int cmd_t4(int argc, char *argv[])
+{
+	int fd1 = -1, fd2 = -1;
+
+	MSGLN("open /a ...");
+	if ((fd1 = uffs_open("/a", UO_RDWR | UO_CREATE)) < 0) {
+		MSGLN("Can't open /a");
+		goto fail_exit;
+	}
+
+	MSGLN("open /b ...");
+	if ((fd2 = uffs_open("/b", UO_RDWR | UO_CREATE)) < 0) {
+		MSGLN("Can't open /b");
+		uffs_close(fd1);
+		goto fail_exit;
+	}
+
+	MSGLN("write (1) to /a ...");
+	uffs_write(fd1, "Hello,", 6);
+	MSGLN("write (1) to /b ...");
+	uffs_write(fd2, "Hello,", 6);
+	MSGLN("write (2) to /a ...");
+	uffs_write(fd1, "World.", 6);
+	MSGLN("write (2) to /b ...");
+	uffs_write(fd2, "World.", 6);
+	MSGLN("close /a ...");
+	uffs_close(fd1);
+	MSGLN("close /b ...");
+	uffs_close(fd2);
+
+	return 0;
+
+fail_exit:
+	return -1;
+}
+
+/* test appending file */
+static int cmd_t5(int argc, char *argv[])
+{
+	int fd = -1;
+	URET ret;
+	char buf[100];
+	const char *name;
+
+	if (argc < 2) {
+		return CLI_INVALID_ARG;
+	}
+
+	name = argv[1];
+
+	fd = uffs_open(name, UO_RDWR|UO_APPEND);
+	if (fd < 0) {
+		MSGLN("Can't open %s", name);
+		goto fail;
+	}
+
+	sprintf(buf, "append test...");
+	ret = uffs_write(fd, buf, strlen(buf));
+	if (ret != strlen(buf)) {
+		MSGLN("write file failed, %d/%d", ret, strlen(buf));
+		ret = -1;
+	}
+	else {
+		MSGLN("write %d bytes to file, content: %s", ret, buf);
+		ret = 0;
+	}
+
+	uffs_close(fd);
+
+	return ret;
+fail:
+	return -1;
+}
+
+
+/* usage: t_pgrw
+ *
+ * This test case test page read/write
+ */
+static int cmd_TestPageReadWrite(int argc, char *argv[])
+{
+	TreeNode *node = NULL;
+	uffs_Device *dev;
+	uffs_Tags local_tag;
+	uffs_Tags *tag = &local_tag;
+	int ret;
+	u16 block;
+	u16 page;
+	uffs_Buf *buf = NULL;
+
+	u32 i;
+	int rc = -1;
+
+	dev = uffs_GetDeviceFromMountPoint("/");
+	if (!dev)
+		goto ext;
+
+	buf = uffs_BufClone(dev, NULL);
+	if (!buf)
+		goto ext;
+
+	node = uffs_TreeGetErasedNode(dev);
+	if (!node) {
+		MSGLN("no free block ?");
+		goto ext;
+	}
+
+	for (i = 0; i < dev->com.pg_data_size; i++) {
+		buf->data[i] = i & 0xFF;
+	}
+
+	block = node->u.list.block;
+	page = 1;
+
+	TAG_DIRTY_BIT(tag) = TAG_DIRTY;
+	TAG_VALID_BIT(tag) = TAG_VALID;
+	TAG_DATA_LEN(tag) = dev->com.pg_data_size;
+	TAG_TYPE(tag) = UFFS_TYPE_DATA;
+	TAG_PAGE_ID(tag) = 3;
+	TAG_PARENT(tag) = 100;
+	TAG_SERIAL(tag) = 10;
+	TAG_BLOCK_TS(tag) = 1;
+	SEAL_TAG(tag);
+
+	ret = uffs_FlashWritePageCombine(dev, block, page, buf, tag);
+	if (UFFS_FLASH_HAVE_ERR(ret)) {
+		MSGLN("Write page error: %d", ret);
+		goto ext;
+	}
+
+	ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE);
+	if (UFFS_FLASH_HAVE_ERR(ret)) {
+		MSGLN("Read page error: %d", ret);
+		goto ext;
+	}
+
+	for (i = 0; i < dev->com.pg_data_size; i++) {
+		if (buf->data[i] != (i & 0xFF)) {
+			MSGLN("Data verify fail at: %d", i);
+			goto ext;
+		}
+	}
+
+	ret = uffs_FlashReadPageTag(dev, block, page, tag);
+	if (UFFS_FLASH_HAVE_ERR(ret)) {
+		MSGLN("Read tag (page spare) error: %d", ret);
+		goto ext;
+	}
+	
+	// verify tag:
+	if (!TAG_IS_SEALED(tag)) {
+		MSGLN("not sealed ? Tag verify fail!");
+		goto ext;
+	}
+
+	if (!TAG_IS_DIRTY(tag)) {
+		MSGLN("not dirty ? Tag verify fail!");
+		goto ext;
+	}
+
+	if (!TAG_IS_VALID(tag)) {
+		MSGLN("not valid ? Tag verify fail!");
+		goto ext;
+	}
+
+	if (TAG_DATA_LEN(tag) != dev->com.pg_data_size ||
+		TAG_TYPE(tag) != UFFS_TYPE_DATA ||
+		TAG_PAGE_ID(tag) != 3 ||
+		TAG_PARENT(tag) != 100 ||
+		TAG_SERIAL(tag) != 10 ||
+		TAG_BLOCK_TS(tag) != 1) {
+
+		MSGLN("Tag verify fail!");
+		goto ext;
+	}
+
+	MSGLN("Page read/write test succ.");
+	rc = 0;
+
+ext:
+	if (node) {
+		uffs_FlashEraseBlock(dev, node->u.list.block);
+		if (HAVE_BADBLOCK(dev))
+			uffs_BadBlockProcess(dev, node);
+		else
+			uffs_TreeInsertToErasedListTail(dev, node);
+	}
+
+	if (dev)
+		uffs_PutDevice(dev);
+
+	if (buf)
+		uffs_BufFreeClone(dev, buf);
+
+	return rc;
+}
+
+/* t_format : test format partition */
+static int cmd_TestFormat(int argc, char *argv[])
+{
+	URET ret;
+	const char *mount = "/";
+	uffs_Device *dev;
+	UBOOL force = U_FALSE;
+	const char *test_file = "/a.txt";
+	int fd;
+	int rc = -1;
+
+	if (argc > 1) {
+		mount = argv[1];
+		if (argc > 2 && strcmp(argv[2], "-f") == 0)
+			force = U_TRUE;
+	}
+
+	fd = uffs_open(test_file, UO_RDWR | UO_CREATE);
+	if (fd < 0) {
+		MSGLN("can't create test file %s", test_file);
+		goto ext;
+	}
+
+	MSGLN("Formating %s ... ", mount);
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point.");
+		goto ext;
+	}
+	else {
+		ret = uffs_FormatDevice(dev, force);
+		if (ret != U_SUCC) {
+			MSGLN("Format fail.");
+		}
+		else {
+			MSGLN("Format succ.");
+			rc = 0;
+		}
+		uffs_PutDevice(dev);
+	}
+
+	uffs_close(fd);  // this should fail on signature check !
+ext:
+	return rc;
+}
+
+
+
+/**
+ * usage: t_pfs <start> <n>
+ *
+ * for example: t_pfs /x/ 100
+ *
+ * This test case performs:
+ *   1) create <n> files under <start>, write full file name as file content
+ *   2) list files under <start>, check files are all listed once
+ *   3) check file content aganist file name
+ *   4) delete files on success
+ */
+static int cmd_TestPopulateFiles(int argc, char *argv[])
+{
+	const char *start = "/";
+	int count = 80;
+	int i, fd, num;
+	char name[128];
+	char buf[128];
+	uffs_DIR *dirp;
+	struct uffs_dirent *ent;
+	unsigned long bitmap[50] = {0};	// one bit per file, maximu 32*50 = 1600 files
+	UBOOL succ = U_TRUE;
+
+#define SBIT(n) bitmap[(n)/(sizeof(bitmap[0]) * 8)] |= (1 << ((n) % (sizeof(bitmap[0]) * 8)))
+#define GBIT(n) (bitmap[(n)/(sizeof(bitmap[0]) * 8)] & (1 << ((n) % (sizeof(bitmap[0]) * 8))))
+
+	if (argc > 1) {
+		start = argv[1];
+		if (argc > 2) {
+			count = strtol(argv[2], NULL, 10);
+		}
+	}
+
+	if (count > sizeof(bitmap) * 8)
+		count = sizeof(bitmap) * 8;
+
+	for (i = 0, fd = -1; i < count; i++) {
+		sprintf(name, "%sFile%03d", start, i);
+		fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC);
+		if (fd < 0) {
+			MSGLN("Create file %s failed", name);
+			break;
+		}
+		if (uffs_write(fd, name, strlen(name)) != strlen(name)) { // write full path name to file
+			MSGLN("Write to file %s failed", name);
+			uffs_close(fd);
+			break;
+		}
+		uffs_close(fd);
+	}
+
+	if (i < count) {
+		// not success, need to clean up
+		for (; i >= 0; i--) {
+			sprintf(name, "%sFile%03d", start, i);
+			if (uffs_remove(name) < 0)
+				MSGLN("Delete file %s failed", name);
+		}
+		succ = U_FALSE;
+		goto ext;
+	}
+
+	MSGLN("%d files created.", count);
+
+	// list files
+	dirp = uffs_opendir(start);
+	if (dirp == NULL) {
+		MSGLN("Can't open dir %s !", start);
+		succ = U_FALSE;
+		goto ext;
+	}
+	ent = uffs_readdir(dirp);
+	while (ent && succ) {
+
+		if (!(ent->d_type & FILE_ATTR_DIR) &&					// not a dir
+			ent->d_namelen == strlen("File000") &&				// check file name length
+			memcmp(ent->d_name, "File", strlen("File")) == 0) {	// file name start with "File"
+			
+			MSGLN("List entry %s", ent->d_name);
+
+			num = strtol(ent->d_name + 4, NULL, 10);
+			if (GBIT(num)) {
+				// file already listed ?
+				MSGLN("File %d listed twice !", ent->d_name);
+				succ = U_FALSE;
+				break;
+			}
+			SBIT(num);
+
+			// check file content
+			sprintf(name, "%s%s", start, ent->d_name);
+			fd = uffs_open(name, UO_RDONLY);
+			if (fd < 0) {
+				MSGLN("Open file %d for read failed !", name);
+			}
+			else {
+				memset(buf, 0, sizeof(buf));
+				num = uffs_read(fd, buf, sizeof(buf));
+				if (num != strlen(name)) {
+					MSGLN("%s Read data length expect %d but got %d !", name, strlen(name), num);
+					succ = U_FALSE;
+				}
+				else {
+					if (memcmp(name, buf, num) != 0) {
+						MSGLN("File %s have wrong content '%s' !", name, buf);
+						succ = U_FALSE;
+					}
+				}
+				uffs_close(fd);
+			}
+		}
+		ent = uffs_readdir(dirp);
+	}
+	uffs_closedir(dirp);
+
+	// check absent files
+	for (i = 0; i < count; i++) {
+		if (GBIT(i) == 0) {
+			sprintf(name, "%sFile%03d", start, i);
+			MSGLN("File %s not listed !", name);
+			succ = U_FALSE;
+		}
+	}
+	
+	// delete files if pass the test
+	for (i = 0; succ && i < count; i++) {
+		sprintf(name, "%sFile%03d", start, i);
+		if (uffs_remove(name) < 0) {
+			MSGLN("Delete file %s failed", name);
+			succ = U_FALSE;
+		}
+	}
+
+ext:
+	MSGLN("Populate files test %s !", succ ? "SUCC" : "FAILED");
+	return succ ? 0 : -1;
+
+}
+
+/**
+ * Open <file> with <oflag>, save fd to $1
+ *
+ *		t_open <oflag> <file>
+ */
+static int cmd_topen(int argc, char *argv[])
+{
+	int fd;
+	const char *name;
+	char *p;
+	int oflag = 0;
+
+	CHK_ARGC(3, 3);
+
+	name = argv[2];
+	p = argv[1];
+	while(*p) {
+		switch(*p++) {
+		case 'a':
+			oflag |= UO_APPEND;
+			break;
+		case 'c':
+			oflag |= UO_CREATE;
+			break;
+		case 't':
+			oflag |= UO_TRUNC;
+			break;
+		case 'w':
+			oflag |= UO_RDWR;
+			break;
+		case 'r':
+			oflag |= UO_RDONLY;
+			break;
+		}
+	}
+
+	fd = uffs_open(name, oflag);
+
+	if (fd >= 0) {
+		cli_env_set('1', fd);
+		return 0;
+	}
+	else {
+		return -1;
+	}
+}
+
+/**
+ * seek file pointer
+ *	t_seek <fd> <offset> [<origin>]
+ * if success, $1 = file position after seek
+ */
+static int cmd_tseek(int argc, char *argv[])
+{
+	int origin = USEEK_SET;
+	int offset;
+	int fd;
+	int ret;
+
+	CHK_ARGC(3, 4);
+
+	if (sscanf(argv[1], "%d", &fd) != 1 ||
+		sscanf(argv[2], "%d", &offset) != 1)
+	{
+		return CLI_INVALID_ARG;
+	}
+
+	if (argc > 3) {
+		switch(argv[3][0]) {
+		case 's':
+			origin = USEEK_SET;
+			break;
+		case 'c':
+			origin = USEEK_CUR;
+			break;
+		case 'e':
+			origin = USEEK_END;
+			break;
+		default:
+			return CLI_INVALID_ARG;
+		}
+	}
+
+	ret = uffs_seek(fd, offset, origin);
+	if (ret >= 0) {
+		cli_env_set('1', ret);
+		return 0;
+	}
+	else {
+		return -1;
+	}
+}
+
+/**
+ * close file
+ *	t_close <fd>
+ */
+static int cmd_tclose(int argc, char *argv[])
+{
+	int fd;
+
+	CHK_ARGC(2, 2);
+
+	if (sscanf(argv[1], "%d", &fd) == 1) {
+		return uffs_close(fd);
+	}
+	else
+		return -1;
+}
+
+/**
+ * write file
+ *	t_write <fd> <txt> [..]
+ */
+static int cmd_twrite(int argc, char *argv[])
+{
+	int fd;
+	int i, len = 0;
+	int ret = 0;
+
+	CHK_ARGC(3, 0);
+	if (sscanf(argv[1], "%d", &fd) != 1) {
+		return -1;
+	}
+	else {
+		for (i = 2; i < argc; i++) {
+			len = strlen(argv[i]);
+			if (uffs_write(fd, argv[i], len) != len) {
+				ret = -1;
+				break;
+			}
+		}
+	}
+
+	if (ret == 0)
+		cli_env_set('1', len);
+
+	return ret;
+}
+
+/**
+ * read and check seq file
+ *	t_check_seq <fd> <size>
+ */
+static int cmd_tcheck_seq(int argc, char *argv[])
+{
+	int fd;
+	int len, size;
+	int ret = 0, r_ret = 0;
+	long pos;
+	u8 buf[MAX_TEST_BUF_LEN];
+	int i;
+	u8 x;
+
+	CHK_ARGC(3, 3);
+
+	if (sscanf(argv[1], "%d", &fd) != 1) {
+		return -1;
+	}
+
+	if (sscanf(argv[2], "%d", &len) != 1) {
+		return -1;
+	}
+
+	pos = uffs_tell(fd);
+	while (len > 0) {
+		size = (len > sizeof(buf) ? sizeof(buf) : len);
+		if ((r_ret = uffs_read(fd, buf, size)) < 0) {
+			MSGLN("Read fail! fd = %d, size = %d, pos = %ld", fd, size, pos);
+			ret = -1;
+			break;
+		}
+
+		// check seq
+		for (i = 0; i < r_ret; i++) {
+			x = (pos + SEQ_INIT + i) % SEQ_MOD_LEN;
+			if (buf[i] != x) {
+				MSGLN("Check fail! fd = %d, pos = %ld (expect 0x%02x but 0x%02x)\n", fd, pos + i, x, buf[i]);
+				ret = -1;
+				break;
+			}
+		}
+
+		if (ret < 0)
+			break;
+
+		len -= r_ret;
+		pos += r_ret;
+	}
+
+	return ret;
+}
+
+
+
+/**
+ * write random seq to file
+ *	t_write_seq <fd> <size>
+ */
+static int cmd_twrite_seq(int argc, char *argv[])
+{
+	int fd;
+	int len = 0, size = 0;
+	long pos = 0;
+	int ret = 0, w_ret = 0;
+	u8 buf[MAX_TEST_BUF_LEN];
+
+	CHK_ARGC(3, 3);
+	if (sscanf(argv[1], "%d", &fd) != 1) {
+		return -1;
+	}
+
+	if (sscanf(argv[2], "%d", &len) != 1) {
+		return -1;
+	}
+
+	pos = uffs_tell(fd);
+	while (len > 0) {
+		size = (len < sizeof(buf) ? len : sizeof(buf));
+		memcp_seq(buf, size, pos);
+		if ((w_ret = uffs_write(fd, buf, size)) < 0) {
+			MSGLN("write fail! fd = %d, size = %d, pos = %ld", fd, size, pos);
+			ret = -1;
+			break;
+		}
+		pos += w_ret;
+		len -= w_ret;
+	}
+
+	if (ret == 0)
+		cli_env_set('1', len);
+
+	return ret;
+}
+
+
+/**
+ * read and check file
+ *	t_read <fd> <txt>
+ */
+static int cmd_tread(int argc, char *argv[])
+{
+	int fd;
+	int len, n;
+	int ret = 0;
+	char buf[64];
+	char *p;
+
+	CHK_ARGC(3, 3);
+
+	if (sscanf(argv[1], "%d", &fd) != 1) {
+		return -1;
+	}
+	else {
+		len = strlen(argv[2]);
+		n = 0;
+		p = argv[2];
+		while (n < len) {
+			n = (len > sizeof(buf) ? sizeof(buf) : len);
+			if (uffs_read(fd, buf, n) != n ||
+				memcmp(buf, p, n) != 0) {
+				ret = -1;
+				break;
+			}
+			len -= n;
+			p += n;
+		}
+	}
+
+	return ret;
+}
+
+
+static void do_dump_page(uffs_Device *dev, uffs_Buf *buf)
+{
+	int i, j;
+	const int line = 16;
+	struct uffs_MiniHeaderSt *header = (struct uffs_MiniHeaderSt *)buf->header;
+	MSG("  header.status = %d\n", header->status);
+	if (header->status != 0xFF) {
+		for (i = 0; i < 64; i += line) {
+			MSG("    ");
+			for (j = 0; j < line; j++)
+				MSG("%02X ", buf->header[i+j]);
+			MSG("\n");
+		}
+		MSG("\n");
+	}
+}
+
+static void do_dump_tag(uffs_Device *dev, uffs_Tags *tag)
+{
+	MSG("  tag sealed: %s\n", TAG_IS_SEALED(tag) ? "yes" : "no");
+	if (TAG_IS_GOOD(tag)) {
+		if (TAG_IS_DIRTY(tag)) {
+			MSG("    block_ts = %d\n", tag->s.block_ts);
+			MSG("    type = %d\n", tag->s.type);
+			MSG("    dirty = %d\n", tag->s.dirty);
+			MSG("    page_id = %d\n", tag->s.page_id);
+			MSG("    serial = %d\n", tag->s.serial);
+			MSG("    parent = %d\n", tag->s.parent);
+			MSG("    data_len = %d\n", tag->s.data_len);
+		}
+		else {
+			MSG("  tag is GOOD but NOT DIRTY !!!???\n");
+		}
+	}
+	else if (TAG_IS_SEALED(tag)) {
+		MSG(" tag is INVALID\n");
+	}
+}
+
+static void do_dump_device(uffs_Device *dev)
+{
+	URET ret;
+	int block, page;
+	uffs_Tags tag;
+	uffs_Buf *buf;
+
+	buf = uffs_BufClone(dev, NULL);
+	if (buf == NULL) {
+		MSGLN("Can't clone buf");
+		return;
+	}
+
+	for (block = dev->par.start; block <= dev->par.end; block++) {
+		MSG("---- block %d ----\n", block);
+		for (page = 0; page < dev->attr->pages_per_block; page++) {
+			MSG("  == page %d ==\n", page);
+			ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE);
+			if (UFFS_FLASH_HAVE_ERR(ret)) {
+				MSG(" !!! Read page failed, ret = %d !!!\n", ret);
+			}
+			else {
+				do_dump_page(dev, buf);
+				if (buf->header[0] != 0xFF) {
+					ret = uffs_FlashReadPageTag(dev, block, page, &tag);
+					if (UFFS_FLASH_HAVE_ERR(ret)) {
+						MSG(" !!! Read TAG failed, ret = %d !!!\n", ret);
+					}
+					else {
+						do_dump_tag(dev, &tag);
+					}
+				}
+			}
+		}
+	}
+	uffs_BufFreeClone(dev, buf);
+}
+
+static int cmd_dump(int argc, char *argv[])
+{
+	const char *mount = "/";
+	uffs_Device *dev;
+
+	if (argc > 1) {
+		mount = argv[1];
+	}
+
+	MSGLN("Dumping %s ... ", mount);
+
+	dev = uffs_GetDeviceFromMountPoint(mount);
+	if (dev == NULL) {
+		MSGLN("Can't get device from mount point.");
+	}
+	else {
+		do_dump_device(dev);
+		uffs_PutDevice(dev);
+	}
+
+	return 0;
+}
+
+static int cmd_apisrv(int argc, char *argv[])
+{
+	return api_server_start();
+}
+
+static const struct cli_command test_cmds[] = 
+{
+    { cmd_t1,					"t1",			"<name>",			"test 1" },
+    { cmd_t2,					"t2",			NULL,				"test 2" },
+    { cmd_t3,					"t3",			"<name> [<noecc>]",	"test 3" },
+    { cmd_t4,					"t4",			NULL,				"test 4" },
+    { cmd_t5,					"t5",			"<name>",			"test 5" },
+    { cmd_TestPageReadWrite,	"t_pgrw",		NULL,				"test page read/write" },
+    { cmd_TestFormat,			"t_format",		NULL,				"test format file system" },
+	{ cmd_TestPopulateFiles,	"t_pfs",		"[<start> [<n>]]",	"test populate <n> files under <start>" },
+	{ cmd_VerifyFile,			"t_vf",			"<file> [<noecc>]", "verify file" },
+
+	{ cmd_topen,				"t_open",		"<oflg> <file>",	"open file, fd save to $1", },
+	{ cmd_tread,				"t_read",		"<fd> <txt>",		"read <fd> and check against <txt>", },
+	{ cmd_tcheck_seq,			"t_check_seq",	"<fd> <size>",		"read seq file <fd> and check", },
+	{ cmd_twrite,				"t_write",		"<fd> <txt> [...]",	"write <fd>", },
+	{ cmd_twrite_seq,			"t_write_seq",	"<fd> <size>",	"write seq file <fd>", },
+	{ cmd_tseek,				"t_seek",		"<fd> <offset> [<origin>]",	"seek <fd> file pointer to <offset> from <origin>", },
+	{ cmd_tclose,				"t_close",		"<fd>",				"close <fd>", },
+	{ cmd_dump,					"dump",			"<mount>",			"dump <mount>", },
+
+	{ cmd_apisrv,				"apisrv",		NULL,				"start API test server", },
+
+    { NULL, NULL, NULL, NULL }
+};
+
+static struct cli_commandset test_cmdset = {
+	test_cmds,
+};
+
+struct cli_commandset * get_test_cmds()
+{
+	return &test_cmdset;
+};
+
+
+

+ 113 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem.c

@@ -0,0 +1,113 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem.c
+ * \brief emulate uffs file system
+ * \author Ricky Zheng, created 9th May, 2005
+ */
+  
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs_fileem.h"
+
+#define PFX "femu: "
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+
+static struct uffs_StorageAttrSt g_femu_storage = {0};
+
+static struct uffs_FileEmuSt g_femu_private = {0};
+
+
+struct uffs_StorageAttrSt * femu_GetStorage()
+{
+	return &g_femu_storage;
+}
+
+struct uffs_FileEmuSt *femu_GetPrivate()
+{
+	return &g_femu_private;
+}
+
+URET femu_InitDevice(uffs_Device *dev)
+{
+	uffs_FileEmu *emu = femu_GetPrivate();
+
+	// setup device storage attr and private data structure.
+	// all femu partition share one storage attribute
+
+	dev->attr = femu_GetStorage();
+	dev->attr->_private = (void *) emu;
+
+	// setup flash driver operations, according to the ecc option.
+	switch(dev->attr->ecc_opt) {
+		case UFFS_ECC_NONE:
+		case UFFS_ECC_SOFT:
+			dev->ops = &g_femu_ops_ecc_soft;
+			break;
+		case UFFS_ECC_HW:
+			dev->ops = &g_femu_ops_ecc_hw;
+			break;
+		case UFFS_ECC_HW_AUTO:
+			dev->ops = &g_femu_ops_ecc_hw_auto;
+			break;
+		default:
+			break;
+	}
+
+#ifdef UFFS_FEMU_ENABLE_INJECTION
+	// setup wrap functions, for inject ECC errors, etc.
+	// check wrap_inited so that multiple devices can share the same driver
+	if (!emu->wrap_inited) {
+		femu_setup_wrapper_functions(dev);
+		emu->wrap_inited = U_TRUE;
+	}
+#endif
+
+	return U_SUCC;
+}
+
+/* Nothing to do here */
+URET femu_ReleaseDevice(uffs_Device *dev)
+{
+	return U_SUCC;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////

+ 88 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem.h

@@ -0,0 +1,88 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_fileem.h
+ * \brief Emulate NAND flash with host file.
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_FILEEM_H_
+#define _UFFS_FILEEM_H_
+
+#include "uffs/uffs_device.h"
+
+#define UFFS_FEMU_FILE_NAME		"uffsemfile.bin"
+
+#define UFFS_FEMU_MAX_BLOCKS	(1024 * 16)		// maximum 16K blocks
+
+#define UFFS_FEMU_ENABLE_INJECTION		// enable bad block & ecc error injection
+
+extern struct uffs_FlashOpsSt g_femu_ops_ecc_soft;		// for software ECC or no ECC.
+extern struct uffs_FlashOpsSt g_femu_ops_ecc_hw;		// for hardware ECC
+extern struct uffs_FlashOpsSt g_femu_ops_ecc_hw_auto;	// for auto hardware ECC
+
+#define PAGE_DATA_WRITE_COUNT_LIMIT		1
+#define PAGE_SPARE_WRITE_COUNT_LIMIT	1
+
+typedef struct uffs_FileEmuSt {
+	int initCount;
+	FILE *fp;
+	FILE *dump_fp;
+	u8 *em_monitor_page;		// page write monitor
+	u8 * em_monitor_spare;		// spare write monitor
+	u32 *em_monitor_block;		// block erease monitor
+	const char *emu_filename;
+#ifdef UFFS_FEMU_ENABLE_INJECTION
+	struct uffs_FlashOpsSt ops_orig;
+	UBOOL wrap_inited;
+#endif
+} uffs_FileEmu;
+
+/* file emulator device init/release entry */
+URET femu_InitDevice(uffs_Device *dev);
+URET femu_ReleaseDevice(uffs_Device *dev);
+
+struct uffs_StorageAttrSt * femu_GetStorage(void);
+struct uffs_FileEmuSt * femu_GetPrivate(void);
+
+#ifdef UFFS_FEMU_ENABLE_INJECTION
+void femu_setup_wrapper_functions(uffs_Device *dev);
+#endif
+
+/* internal used functions, shared by all ecc option implementations */
+int femu_InitFlash(uffs_Device *dev);
+int femu_ReleaseFlash(uffs_Device *dev);
+int femu_EraseBlock(uffs_Device *dev, u32 blockNumber);
+
+#endif
+

+ 236 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw.c

@@ -0,0 +1,236 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2010 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem_ecc_hw.c
+ * \brief emulate uffs file system for hardware ECC.
+ *
+ *	 In this emulator, we call 'uffs_FlashMakeSpare()' to do the layout job
+ *	 and call 'uffs_EccMake()' to calculate ECC.
+ *
+ * \author Ricky Zheng @ Oct, 2010
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs_fileem.h"
+#include "uffs/uffs_ecc.h"
+
+#define PFX "femu: "
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+static int femu_hw_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts)
+{
+	int written;
+	int abs_page;
+	int full_page_size;
+	uffs_FileEmu *emu;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	u8 spare[UFFS_MAX_SPARE_SIZE];
+	u8 ecc_buf[UFFS_MAX_ECC_SIZE];
+	int spare_len;
+
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto err;
+	}
+
+	abs_page = attr->pages_per_block * block + page;
+	full_page_size = attr->page_data_size + attr->spare_size;
+
+	if (data && data_len > 0) {
+		if (data_len > attr->page_data_size)
+			goto err;
+
+		emu->em_monitor_page[abs_page]++;
+		if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
+			MSG("Warrning: block %d page %d exceed it's maximum write time!", block, page);
+			goto err;
+		}
+		
+		fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
+
+		written = fwrite(data, 1, data_len, emu->fp);
+		
+		if (written != data_len) {
+			MSG("write page I/O error ?");
+			goto err;
+		}
+
+		dev->st.page_write_count++;
+		dev->st.io_write += written;
+
+	}
+
+	if (ts) {
+
+		emu->em_monitor_spare[abs_page]++;
+		if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
+			MSG("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page);
+			goto err;
+		}
+
+		if (!uffs_Assert(data != NULL, "BUG: Write spare without data ?"))
+			goto err;
+
+		uffs_EccMake(data, data_len, ecc_buf);
+		uffs_FlashMakeSpare(dev, ts, ecc_buf, spare);
+		spare_len = dev->mem.spare_data_size;
+		
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
+		written = fwrite(spare, 1, spare_len, emu->fp);
+		if (written != spare_len) {
+			MSG("write spare I/O error ?");
+			goto err;
+		}
+
+		dev->st.spare_write_count++;
+		dev->st.io_write += written;
+	}
+
+	if (data == NULL && ts == NULL) {
+		// mark bad block
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
+		written = fwrite("\0", 1, 1, emu->fp);
+		if (written != 1) {
+			MSG("write bad block mark I/O error ?");
+			goto err;
+		}
+		dev->st.io_write++;
+	}
+
+	fflush(emu->fp);
+	return UFFS_FLASH_NO_ERR;
+err:
+	fflush(emu->fp);
+	return UFFS_FLASH_IO_ERR;
+}
+
+
+static URET femu_hw_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
+									uffs_TagStore *ts, u8 *ecc_store)
+{
+	int nread;
+	uffs_FileEmu *emu;
+	int abs_page;
+	int full_page_size;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	unsigned char status;
+	u8 spare[UFFS_MAX_SPARE_SIZE];
+	int spare_len;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto err;
+	}
+
+	abs_page = attr->pages_per_block * block + page;
+	full_page_size = attr->page_data_size + attr->spare_size;
+
+	if (data && data_len > 0) {
+		if (data_len > attr->page_data_size)
+			goto err;
+
+		fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
+		nread = fread(data, 1, data_len, emu->fp);
+
+		if (nread != data_len) {
+			MSG("read page I/O error ?");
+			goto err;
+		}
+		dev->st.io_read += nread;
+		dev->st.page_read_count++;
+
+		if (ecc) {
+			// calculate ECC for data
+			uffs_EccMake(data, data_len, ecc);
+		}
+	}
+
+	if (ts) {
+
+		spare_len = dev->mem.spare_data_size;
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
+		nread = fread(spare, 1, spare_len, emu->fp);
+
+		if (nread != spare_len) {
+			MSG("read page spare I/O error ?");
+			goto err;
+		}
+
+		// unload ts and ecc from spare
+		uffs_FlashUnloadSpare(dev, spare, ts, ecc_store);
+
+		dev->st.io_read += nread;
+		dev->st.spare_read_count++;
+	}
+
+	if (data == NULL && ts == NULL) {
+		// read bad block mark
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
+		nread = fread(&status, 1, 1, emu->fp);
+
+		if (nread != 1) {
+			MSG("read badblock mark I/O error ?");
+			goto err;
+		}
+		dev->st.io_read++;
+
+		return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
+	}
+
+	return UFFS_FLASH_NO_ERR;
+err:
+	return UFFS_FLASH_IO_ERR;
+}
+
+
+uffs_FlashOps g_femu_ops_ecc_hw = {
+	femu_InitFlash,				// InitFlash()
+	femu_ReleaseFlash,			// ReleaseFlash()
+	NULL,						// ReadPage()
+	femu_hw_ReadPageWithLayout,	// ReadPageWithLayout()
+	NULL,						// WritePage()
+	femu_hw_WritePageWithLayout,// WritePageWithLayout()
+	NULL,						// IsBadBlock(), let UFFS take care of it.
+	NULL,						// MarkBadBlock(), let UFFS take care of it.
+	femu_EraseBlock,			// EraseBlock()
+};

+ 356 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw_auto.c

@@ -0,0 +1,356 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2010 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem_ecc_hw_auto.c
+ *
+ * \brief Emulate uffs file system for auto hardware ECC or RS error collection.
+ *
+ *    This emulator emulate LPC32x0 MLC NAND controller which generate 10 bytes
+ *    Reed-Solomon error correction code (RS-ECC) for every 518 bytes data.
+ *
+ *    For small page MLC have 16 bytes spare area leves only 6 bytes for 'meta-data',
+ *    no enough room for UFFS's 8 bytes tag and bad block mark. For this reason,
+ *    we adjust page data/spare boundary to 508/20.
+ *
+ *    This emulator does not calculate real RS-ECC code, instead, we use software ECC
+ *    to calculate 6 bytes ECC code, so this solution does not have the same error
+ *    correcting cabability of RS-ECC.
+ *
+ *    Note: the MLC controller strictly require sequencial access to serial data buffer.
+ *
+ * \author Ricky Zheng @ Oct, 2010
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_ecc.h"
+#include "uffs_fileem.h"
+
+#define PFX "femu: "
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+#define RS_ECC_SIZE			10
+#define PAGE_DATA_SIZE		508
+#define PAGE_SPARE_SIZE		20
+#define PAGE_FULL_SIZE		(PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
+static u8 g_sdata_buf[PAGE_FULL_SIZE];	// emulating LPC32x0's 528-bytes serial data buffer
+
+static int g_sdata_buf_pointer = 0;
+
+static void start_sdata_access()
+{
+	g_sdata_buf_pointer = 0;
+}
+
+static void feed_sdata(const u8 *data, int len)
+{
+	if (!uffs_Assert(g_sdata_buf_pointer + len <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!"))
+		return;
+
+	if (data)
+		memcpy(g_sdata_buf + g_sdata_buf_pointer, data, len);
+	g_sdata_buf_pointer += len;
+}
+
+static void feed_sdata_constant(u8 val, int num)
+{
+	if (!uffs_Assert(g_sdata_buf_pointer + num <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!"))
+		return;
+
+	memset(g_sdata_buf + g_sdata_buf_pointer, val, num);
+	g_sdata_buf_pointer += num;
+}
+
+static void drain_sdata(u8 *data, int len)
+{
+	if (!uffs_Assert( (int)sizeof(g_sdata_buf) - g_sdata_buf_pointer >= len, "BUG: Serial Data Buffer overdrain !!"))
+		return;
+
+	if (data)
+		memcpy(data, g_sdata_buf + g_sdata_buf_pointer, len);
+	g_sdata_buf_pointer += len;
+}
+
+static int load_sdata(uffs_Device *dev, int block, int page)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	int abs_page;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	int nread;
+	int ret;
+	u8 ecc_buf[RS_ECC_SIZE];
+	u8 *ecc_store;
+
+	abs_page = attr->pages_per_block * block + page;
+
+	fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET);
+	nread = fread(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp);
+	g_sdata_buf_pointer = 0;
+
+	ret = ((nread == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR);
+
+	if (ret == UFFS_FLASH_NO_ERR) {
+
+		// Perform ECC check & correction
+		// In the real world, this is done by MLC controller hardware
+		memset(ecc_buf, 0xFF, RS_ECC_SIZE);
+		uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf);
+
+		ecc_store = g_sdata_buf + PAGE_FULL_SIZE - RS_ECC_SIZE;
+
+		ret = uffs_EccCorrect(g_sdata_buf, attr->page_data_size, ecc_store, ecc_buf);
+
+		ret = (ret < 0 ? UFFS_FLASH_ECC_FAIL :
+				(ret > 0 ? UFFS_FLASH_ECC_OK : UFFS_FLASH_NO_ERR));
+		
+	}
+
+	return ret;
+}
+
+static int program_sdata(uffs_Device *dev, int block, int page)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	int abs_page;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	u8 ecc_buf[RS_ECC_SIZE];
+	int writtern = 0;
+
+	// In the real world, MLC controller will generate RS-ECC code in serial data buffer
+	// and might start auto programing NAND flash. Here, we use software ECC to emulate RS-ECC.
+	memset(ecc_buf, 0xFF, sizeof(ecc_buf));
+	uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf);
+	feed_sdata(ecc_buf, RS_ECC_SIZE);
+
+	if (!uffs_Assert(g_sdata_buf_pointer == PAGE_FULL_SIZE, "Serial Data Buffer is not fully filled !!"))
+		goto ext;
+
+	abs_page = attr->pages_per_block * block + page;
+
+	fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET);
+	writtern = fwrite(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp);
+ext:
+	return (writtern == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR;
+}
+
+
+static int femu_hw_auto_InitFlash(uffs_Device *dev)
+{
+	struct uffs_StorageAttrSt *attr = dev->attr;
+
+	// now this is a good chance to adjust page data/spare boundary
+	if (attr->page_data_size + attr->spare_size != PAGE_FULL_SIZE) {
+		MSGLN("This emulator emulates only for page size %d bytes !", PAGE_FULL_SIZE);
+		return -1;
+	}
+	if (attr->spare_size < PAGE_SPARE_SIZE) {
+		attr->page_data_size -= (PAGE_SPARE_SIZE - attr->spare_size);
+		attr->spare_size = PAGE_SPARE_SIZE;
+		MSGLN("Adjust page data/spare boundary to %d/%d", attr->page_data_size, attr->spare_size);
+	}
+
+	// and fix ECC size
+	attr->ecc_size = RS_ECC_SIZE;
+	MSGLN("Adjust ECC size to %d bytes", attr->ecc_size);
+	
+	return femu_InitFlash(dev);
+}
+
+
+static int femu_hw_auto_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts)
+{
+	int abs_page;
+	uffs_FileEmu *emu;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	u8 spare[PAGE_SPARE_SIZE];
+	int ret = UFFS_FLASH_IO_ERR;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto err;
+	}
+
+	abs_page = attr->pages_per_block * block + page;
+
+	start_sdata_access();
+
+	dev->st.page_write_count++;
+	dev->st.spare_write_count++;
+	dev->st.io_write += PAGE_FULL_SIZE;
+
+	if (data || ts) {
+		// normal page write
+		if (data && data_len > 0) {
+			if (data_len > attr->page_data_size)
+				goto err;
+
+			emu->em_monitor_page[abs_page]++;
+			if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
+				MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page);
+				goto err;
+			}
+			
+			// Copy data to serial data buffer
+			feed_sdata(data, data_len);
+
+			// Pad the rest data as 0xFF
+			feed_sdata_constant(0xFF, attr->page_data_size - data_len);
+
+		}
+		else {
+			// We still need to feed data to serial data buffer to make MLC controller happy
+			// The current UFFS won't write ts only, so we'll never run to here.
+			feed_sdata_constant(0xFF, attr->page_data_size);
+		}
+
+		if (ts) {
+
+			emu->em_monitor_spare[abs_page]++;
+			if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
+				MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page);
+				goto err;
+			}
+
+			memset(spare, 0xFF, sizeof(spare));
+			uffs_FlashMakeSpare(dev, ts, NULL, spare);	// do not pack ECC, as MLC controller will
+														// automatically write RS-ECC to the latest 10 bytes.
+
+			// feed spare data to serial data buffer
+			feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);			
+		}
+	}
+	else {
+		// mark bad block
+
+		// feed data to serial data buffer to make MLC controller happy
+		feed_sdata_constant(0xFF, attr->page_data_size);
+
+		memset(spare, 0xFF, sizeof(spare));
+		spare[attr->block_status_offs] = 0;
+
+		// feed spare data to serial data buffer
+		feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);
+
+		dev->st.io_write++;
+	}
+
+	// now, program serial data buffer to NAND flash
+	ret = program_sdata(dev, block, page);
+
+	fflush(emu->fp);
+	return ret;
+err:
+	fflush(emu->fp);
+	return ret;
+}
+
+
+static URET femu_hw_auto_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
+									uffs_TagStore *ts, u8 *ecc_store)
+{
+	uffs_FileEmu *emu;
+	int abs_page;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	unsigned char status;
+	u8 spare[PAGE_SPARE_SIZE];
+	int ret = UFFS_FLASH_IO_ERR;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto ext;
+	}
+
+	abs_page = attr->pages_per_block * block + page;
+
+	// now load full page to serial data buffer
+	ret = load_sdata(dev, block, page);
+	if (ret != UFFS_FLASH_NO_ERR)
+		goto ext;
+
+	start_sdata_access();
+
+	dev->st.io_read += PAGE_FULL_SIZE;
+	dev->st.page_read_count++;
+	dev->st.spare_read_count++;
+
+	if (data || ts) {
+
+		if (data && data_len > 0) {
+			if (data_len > attr->page_data_size)
+				goto ext;
+
+			drain_sdata(data, data_len);
+		}
+
+		if (ts) {
+			if (g_sdata_buf_pointer < attr->page_data_size)
+				drain_sdata(NULL, attr->page_data_size - g_sdata_buf_pointer);
+
+			drain_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);
+
+			// unload ts from spare
+			uffs_FlashUnloadSpare(dev, spare, ts, NULL);
+		}
+	}
+	else {
+		// read bad block mark
+		drain_sdata(NULL, attr->page_data_size + attr->block_status_offs - 1);
+		drain_sdata(&status, 1);
+
+		ret = (status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
+	}
+
+ext:
+	return ret;
+}
+
+
+uffs_FlashOps g_femu_ops_ecc_hw_auto = {
+	femu_hw_auto_InitFlash,				// InitFlash()
+	femu_ReleaseFlash,					// ReleaseFlash()
+	NULL,								// ReadPage()
+	femu_hw_auto_ReadPageWithLayout,	// ReadPageWithLayout()
+	NULL,								// WritePage()
+	femu_hw_auto_WritePageWithLayout,	// WirtePageWithLayout()
+	NULL,						// IsBadBlock(), let UFFS take care of it.
+	NULL,						// MarkBadBlock(), let UFFS take care of it.
+	femu_EraseBlock,			// EraseBlock()
+};

+ 212 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_soft.c

@@ -0,0 +1,212 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2010 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem_ecc_soft.c
+ * \brief emulate uffs file system for software ECC
+ * \author Ricky Zheng @ Oct, 2010
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_flash.h"
+#include "uffs_fileem.h"
+
+#define PFX "femu: "
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+static int femu_WritePage(uffs_Device *dev, u32 block, u32 page_num,
+							const u8 *data, int data_len, const u8 *spare, int spare_len)
+{
+	int written;
+	int abs_page;
+	int full_page_size;
+	uffs_FileEmu *emu;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto err;
+	}
+
+	abs_page = attr->pages_per_block * block + page_num;
+	full_page_size = attr->page_data_size + attr->spare_size;
+
+	if (data && data_len > 0) {
+		if (data_len > attr->page_data_size)
+			goto err;
+
+		emu->em_monitor_page[abs_page]++;
+		if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
+			MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page_num);
+			goto err;
+		}
+		
+		fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
+
+		written = fwrite(data, 1, data_len, emu->fp);
+		
+		if (written != data_len) {
+			MSGLN("write page I/O error ?");
+			goto err;
+		}
+
+		dev->st.page_write_count++;
+		dev->st.io_write += written;
+	}
+
+	if (spare && spare_len > 0) {
+		if (spare_len > attr->spare_size)
+			goto err;
+
+		emu->em_monitor_spare[abs_page]++;
+		if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
+			MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page_num);
+			goto err;
+		}
+		
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
+		written = fwrite(spare, 1, spare_len, emu->fp);
+		if (written != spare_len) {
+			MSGLN("write spare I/O error ?");
+			goto err;
+		}
+
+		dev->st.spare_write_count++;
+		dev->st.io_write += written;
+	}
+
+	if (data == NULL && spare == NULL) {
+		// mark bad block
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
+		written = fwrite("\0", 1, 1, emu->fp);
+		if (written != 1) {
+			MSGLN("write bad block mark I/O error ?");
+			goto err;
+		}
+		dev->st.io_write++;
+	}
+
+	fflush(emu->fp);
+	return UFFS_FLASH_NO_ERR;
+err:
+	fflush(emu->fp);
+	return UFFS_FLASH_IO_ERR;
+}
+
+
+static URET femu_ReadPage(uffs_Device *dev, u32 block, u32 page_num, u8 *data, int data_len, u8 *ecc,
+							u8 *spare, int spare_len)
+{
+	int nread;
+	uffs_FileEmu *emu;
+	int abs_page;
+	int full_page_size;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	unsigned char status;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (!emu || !(emu->fp)) {
+		goto err;
+	}
+
+	abs_page = attr->pages_per_block * block + page_num;
+	full_page_size = attr->page_data_size + attr->spare_size;
+
+	if (data && data_len > 0) {
+		if (data_len > attr->page_data_size)
+			goto err;
+
+		fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
+		nread = fread(data, 1, data_len, emu->fp);
+
+		if (nread != data_len) {
+			MSGLN("read page I/O error ?");
+			goto err;
+		}
+		dev->st.io_read += nread;
+		dev->st.page_read_count++;
+	}
+
+	if (spare && spare_len > 0) {
+		if (spare_len > attr->spare_size)
+			goto err;
+
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
+		nread = fread(spare, 1, spare_len, emu->fp);
+
+		if (nread != spare_len) {
+			MSGLN("read page spare I/O error ?");
+			goto err;
+		}
+		dev->st.io_read += nread;
+		dev->st.spare_read_count++;
+	}
+
+	if (data == NULL && spare == NULL) {
+		// read bad block mark
+		fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
+		nread = fread(&status, 1, 1, emu->fp);
+
+		if (nread != 1) {
+			MSGLN("read badblock mark I/O error ?");
+			goto err;
+		}
+		dev->st.io_read++;
+
+		return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
+	}
+
+	return UFFS_FLASH_NO_ERR;
+err:
+	return UFFS_FLASH_IO_ERR;
+}
+
+
+uffs_FlashOps g_femu_ops_ecc_soft = {
+	femu_InitFlash,		// InitFlash()
+	femu_ReleaseFlash,	// ReleaseFlash()
+	femu_ReadPage,		// ReadPage()
+	NULL,				// ReadPageWithLayout
+	femu_WritePage,		// WritePage()
+	NULL,				// WirtePageWithLayout
+	NULL,				// IsBadBlock(), let UFFS take care of it.
+	NULL,				// MarkBadBlock(), let UFFS take care of it.
+	femu_EraseBlock,	// EraseBlock()
+};

+ 232 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem_share.c

@@ -0,0 +1,232 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem_share.c
+ * \brief emulate uffs file system, shared functions
+ * \author Ricky Zheng, created Nov, 2010
+ */
+  
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs_fileem.h"
+
+#define PFX "femu: "
+
+/****************************************************************/
+/*           Shared flash driver functions:                     */
+/*                                                              */
+/*   femu_InitFlash(), femu_ReleaseFlash(), femu_EraseBlock()   */
+/*                                                              */
+/****************************************************************/
+
+static u8 g_page_buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];
+
+/*
+ * Create emulator disk, initialise monitors, inject manufacture bad blocks, etc.
+ *
+ */
+int femu_InitFlash(uffs_Device *dev)
+{
+	int i;
+	int fSize;
+	int written;
+	u8 * p = g_page_buf;
+	uffs_FileEmu *emu;
+
+	struct uffs_StorageAttrSt *attr = dev->attr;
+
+	int full_page_size = attr->page_data_size + attr->spare_size;
+	int total_pages = attr->total_blocks * attr->pages_per_block;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	if (emu->initCount > 0) {
+		emu->initCount++;
+		return 0;
+	}
+
+	if (emu->emu_filename == NULL)
+		emu->emu_filename = UFFS_FEMU_FILE_NAME;
+
+	uffs_Perror(UFFS_MSG_NORMAL,  "femu device init.");
+
+	emu->em_monitor_page = (u8 *) malloc(sizeof(emu->em_monitor_page[0]) * total_pages);
+	if (!emu->em_monitor_page)
+		return -1;
+	emu->em_monitor_spare = (u8 *) malloc(sizeof(emu->em_monitor_spare[0]) * total_pages);
+	if (!emu->em_monitor_spare)
+		return -1;
+
+	emu->em_monitor_block = (u32 *) malloc(sizeof(emu->em_monitor_block[0]) * attr->total_blocks);
+	if (!emu->em_monitor_block)
+		return -1;
+
+	//clear monitor
+	memset(emu->em_monitor_page, 0, sizeof(emu->em_monitor_page[0]) * total_pages);
+	memset(emu->em_monitor_spare, 0, sizeof(emu->em_monitor_spare[0]) * total_pages);
+	memset(emu->em_monitor_block, 0, sizeof(emu->em_monitor_block[0]) * attr->total_blocks);
+
+	emu->fp = fopen(emu->emu_filename, "rb");
+	if (emu->fp == NULL) {
+		emu->fp = fopen(emu->emu_filename, "ab+");
+		if (emu->fp == NULL) {
+			printf(PFX"Failed to create uffs emulation file.");
+			return -1;
+		}
+
+		fseek(emu->fp, 0, SEEK_END);
+		fSize = ftell(emu->fp);
+		
+		if (fSize < total_pages * full_page_size)	{
+			printf("Creating uffs emulation file\n");
+			fseek(emu->fp, 0, SEEK_SET);
+			memset(p, 0xff, full_page_size);
+			for (i = 0; i < total_pages; i++)	{
+				written = fwrite(p, 1, full_page_size, emu->fp);
+				if (written != full_page_size)	{
+					printf("Write failed\n");
+					fclose(emu->fp);
+					emu->fp = NULL;
+					return -1;
+				}
+			}		
+		}
+	}
+
+	fflush(emu->fp);	
+	fclose(emu->fp);
+
+	emu->fp = fopen(emu->emu_filename, "rb+");
+	if (emu->fp == NULL) {
+		printf(PFX"Can't open emulation file.\n");
+		return -1;
+	}
+
+	emu->initCount++;
+
+	return 0;
+}
+
+/*
+ * Release resources
+ */
+int femu_ReleaseFlash(uffs_Device *dev)
+{
+	uffs_FileEmu *emu;
+
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	emu->initCount--;
+
+	if (emu->initCount == 0) {
+
+		uffs_Perror(UFFS_MSG_NORMAL,  "femu device release.");
+
+		if (emu->fp) {
+			fclose(emu->fp);
+			emu->fp = NULL;
+		}
+
+		if (emu->em_monitor_page)
+			free(emu->em_monitor_page);
+		if (emu->em_monitor_spare) 
+			free(emu->em_monitor_spare);
+		if (emu->em_monitor_block)
+			free(emu->em_monitor_block);
+		emu->em_monitor_page = NULL;
+		emu->em_monitor_spare = NULL;
+		emu->em_monitor_block = NULL;
+	}
+
+	return 0;
+}
+
+int femu_EraseBlock(uffs_Device *dev, u32 blockNumber)
+{
+
+	int i;
+	u8 * pg = g_page_buf;
+	int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
+	uffs_FileEmu *emu;
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+	if (!emu || !(emu->fp))
+		goto err;
+
+	pg_size = dev->attr->page_data_size + dev->attr->spare_size;
+	pgd_size = dev->attr->page_data_size;
+	sp_size = dev->attr->spare_size;
+	blk_pgs = dev->attr->pages_per_block;
+	blks = dev->attr->total_blocks;
+	blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
+	
+	printf("femu: erase block %d\n", blockNumber);
+
+	if ((int)blockNumber >= blks) {
+		printf("Attempt to erase non-existant block %d\n",blockNumber);
+		goto err;
+	}
+	else {
+
+		//clear this block monitors
+		memset(emu->em_monitor_page + (blockNumber * blk_pgs), 
+			0, 
+			blk_pgs * sizeof(u8));
+		memset(emu->em_monitor_spare + (blockNumber * blk_pgs),
+			0,
+			blk_pgs * sizeof(u8));
+
+		emu->em_monitor_block[blockNumber]++;
+		
+		memset(pg, 0xff, (pgd_size + sp_size));
+		
+		fseek(emu->fp, blockNumber * blk_pgs * (pgd_size + sp_size), SEEK_SET);
+		
+		for (i = 0; i < blk_pgs; i++)	{
+			fwrite(pg, 1, (pgd_size + sp_size), emu->fp);
+		}
+
+		fflush(emu->fp);
+		dev->st.block_erase_count++;
+	}
+
+	return UFFS_FLASH_NO_ERR;
+err:
+	return UFFS_FLASH_IO_ERR;
+	
+}
+

+ 311 - 0
components/dfs/filesystems/uffs/src/emu/uffs_fileem_wrap.c

@@ -0,0 +1,311 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fileem_wrap.c
+ *
+ * \brief file emulator wrapper functions for injecting bad blocks or ECC errors.
+ *
+ * \author Ricky Zheng, created Nov, 2010
+ */
+
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_device.h"
+#include "uffs_fileem.h"
+
+#define PFX "femu: "
+#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__)
+
+// #define UFFS_FEMU_SHOW_FLASH_IO
+
+#ifdef UFFS_FEMU_ENABLE_INJECTION
+
+struct uffs_FileEmuBitFlip {
+	int block;
+	int page;
+	int offset;
+	u8 mask;
+};
+
+/* simulate bad blocks */
+#define FILEEMU_STOCK_BAD_BLOCKS	{5, 180}	// bad block come from manufacture
+#define FILEEMU_ERASE_BAD_BLOCKS	{100, 150}	// new bad block discovered when erasing
+
+/* simulating bit flip */
+#define FILEEMU_WRITE_BIT_FLIP \
+	{ \
+		{20, 2, 10, 1 << 4},	/* block 20, page 2, offset 10, bit 4 */	\
+		{24, 4, -3, 1 << 2},	/* block 24, page 4, spare offset 3, bit 2*/ \
+		{60, 1, 5, 1 << 3},		/* block 60, page 1, offset 5, bit 3 */ \
+		{66, 1, 15, 1 << 7},	/* block 66, page 1, offset 300, bit 7 */ \
+		{80, 2, 2, 1 << 1},		/* block 80, page 2, offset 2, bit 1 */ \
+		{88, 2, 100, 1 << 5},	/* block 88, page 2, offset 100, bit 5 */ \
+	}
+
+
+static int femu_InitFlash_wrap(uffs_Device *dev);
+
+static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
+							u8 *spare, int spare_len);
+static int femu_ReadPageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
+									uffs_TagStore *ts, u8 *ecc_store);
+static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *spare, int spare_len);
+static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc,
+									const uffs_TagStore *ts);
+static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber);
+
+
+/////////////////////////////////////////////////////////////////////////////////
+
+void femu_setup_wrapper_functions(uffs_Device *dev)
+{
+	uffs_FileEmu *emu;
+	emu = (uffs_FileEmu *)(dev->attr->_private);
+
+	// setup wrap functions, for inject ECC errors, etc.
+
+	memcpy(&emu->ops_orig, dev->ops, sizeof(struct uffs_FlashOpsSt));
+
+	if (dev->ops->InitFlash)
+		dev->ops->InitFlash = femu_InitFlash_wrap;
+	if (dev->ops->EraseBlock)
+		dev->ops->EraseBlock = femu_EraseBlock_wrap;
+	if (dev->ops->ReadPage)
+		dev->ops->ReadPage = femu_ReadPage_wrap;
+	if (dev->ops->ReadPageWithLayout)
+		dev->ops->ReadPageWithLayout = femu_ReadPageWithLayout_wrap;
+	if (dev->ops->WritePage)
+		dev->ops->WritePage = femu_WritePage_wrap;
+	if (dev->ops->WritePageWithLayout)
+		dev->ops->WritePageWithLayout = femu_WritePageWithLayout_wrap;
+}
+
+static int femu_InitFlash_wrap(uffs_Device *dev)
+{
+	int ret;
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+
+#ifdef FILEEMU_STOCK_BAD_BLOCKS
+	u32 bad_blocks[] = FILEEMU_STOCK_BAD_BLOCKS;
+	int j;
+	u8 x = 0;
+	struct uffs_StorageAttrSt *attr = dev->attr;
+	int full_page_size = attr->page_data_size + attr->spare_size;
+	int blk_size = full_page_size * attr->pages_per_block;
+#endif
+
+	if (emu->initCount == 0) {
+		ret = emu->ops_orig.InitFlash(dev);
+#ifdef FILEEMU_STOCK_BAD_BLOCKS
+		if (ret >= 0) {
+			for (j = 0; j < ARRAY_SIZE(bad_blocks); j++) {
+				if (bad_blocks[j] < dev->attr->total_blocks) {
+					printf(" --- manufacture bad block %d ---\n", bad_blocks[j]);
+					fseek(emu->fp, bad_blocks[j] * blk_size + attr->page_data_size + dev->attr->block_status_offs, SEEK_SET);
+					fwrite(&x, 1, 1, emu->fp);
+				}
+			}
+		}
+#endif
+	}
+	else {
+		ret = emu->ops_orig.InitFlash(dev);
+	}
+
+	return ret;
+}
+
+static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
+							u8 *spare, int spare_len)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+
+#ifdef UFFS_FEMU_SHOW_FLASH_IO
+	if (data || spare) {
+		MSG(PFX " Read block %d page %d", block, page);
+		if (data)
+			MSG(" DATA[%d]", data_len);
+		if (spare)
+			MSG(" SPARE[%d]", spare_len);
+		MSG(TENDSTR);
+	}
+#endif
+	return emu->ops_orig.ReadPage(dev, block, page, data, data_len, ecc, spare, spare_len);
+}
+
+static int femu_ReadPageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
+									uffs_TagStore *ts, u8 *ecc_store)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+
+#ifdef UFFS_FEMU_SHOW_FLASH_IO
+	if (data || ts) {
+		MSG(PFX " Read block %d page %d", block, page);
+		if (data)
+			MSG(" DATA[%d]", data_len);
+		if (ts)
+			MSG(" TS");
+		MSG(TENDSTR);
+	}
+#endif
+	return emu->ops_orig.ReadPageWithLayout(dev, block, page, data, data_len, ecc, ts, ecc_store);
+}
+
+
+////////////////////// wraper functions ///////////////////////////
+
+static void InjectBitFlip(uffs_Device *dev, u32 block, u32 page)
+{
+#ifdef FILEEMU_WRITE_BIT_FLIP
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	struct uffs_FileEmuBitFlip flips[] = FILEEMU_WRITE_BIT_FLIP;
+	struct uffs_FileEmuBitFlip *x;
+	u8 buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];
+	u8 *data = buf;
+	u8 *spare = buf + dev->attr->page_data_size;
+	int full_page_size = dev->attr->page_data_size + dev->attr->spare_size;
+	int blk_size = full_page_size * dev->attr->pages_per_block;
+	int page_offset = block * blk_size + full_page_size * page;
+
+	int i;
+	u8 *p;
+
+	fseek(emu->fp, page_offset, SEEK_SET);
+	fread(buf, 1, full_page_size, emu->fp);
+
+	p = NULL;
+	for (i = 0; i < ARRAY_SIZE(flips); i++) {
+		x = &flips[i];
+		if (x->block == block && x->page == page) {
+			if (x->offset >= 0) {
+				printf(" --- Inject data bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, x->offset, x->mask);
+				p = (u8 *)(data + x->offset);
+			}
+			else {
+				printf(" --- Inject spare bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, -x->offset, x->mask);
+				p = (u8 *)(spare - x->offset);
+			}
+			*p = (*p & ~x->mask) | (~(*p & x->mask) & x->mask);
+		}
+	}
+
+	if (p) {
+		fseek(emu->fp, page_offset, SEEK_SET);
+		fwrite(buf, 1, full_page_size, emu->fp);
+	}
+#endif	
+}
+
+static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *spare, int spare_len)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	int ret;
+
+#ifdef UFFS_FEMU_SHOW_FLASH_IO
+	if (data || spare) {
+		MSG(PFX " Write block %d page %d", block, page);
+		if (data)
+			MSG(" DATA[%d]", data_len);
+		if (spare)
+			MSG(" SPARE[%d]", spare_len);
+		MSG(TENDSTR);
+	}
+#endif
+	
+	ret = emu->ops_orig.WritePage(dev, block, page, data, data_len, spare, spare_len);
+
+	InjectBitFlip(dev, block, page);
+
+	return ret;
+}
+
+static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc,
+									const uffs_TagStore *ts)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+	int ret;
+	
+#ifdef UFFS_FEMU_SHOW_FLASH_IO
+	if (data || ts) {
+		MSG(PFX " Write block %d page %d", block, page);
+		if (data)
+			MSG(" DATA[%d]", data_len);
+		if (ts)
+			MSG(" TS");
+		MSG(TENDSTR);
+	}
+#endif
+
+	ret = emu->ops_orig.WritePageWithLayout(dev, block, page, data, data_len, ecc, ts);
+
+	InjectBitFlip(dev, block, page);
+
+	return ret;
+}
+
+
+static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber)
+{
+	uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
+
+#ifdef FILEEMU_ERASE_BAD_BLOCKS
+	int blocks[] = FILEEMU_ERASE_BAD_BLOCKS;
+	int i;
+	URET ret;
+	ret = emu->ops_orig.EraseBlock(dev, blockNumber);
+
+	for (i = 0; i < ARRAY_SIZE(blocks); i++) {
+		if (blockNumber == blocks[i]) {
+			printf(" --- Inject bad block%d when erasing --- \n", blockNumber);
+			ret = UFFS_FLASH_BAD_BLK;
+		}
+	}
+
+	return ret;		
+
+#else
+
+	return emu->ops_orig.EraseBlock(dev, blockNumber);
+
+#endif
+}
+
+#endif // UFFS_FEMU_ENABLE_INJECTION
+
+/////////////////////////////////////////////////////////////////////////////////

+ 22 - 0
components/dfs/filesystems/uffs/src/example/CMakeLists.txt

@@ -0,0 +1,22 @@
+IF (UNIX)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix)
+ENDIF()
+IF (WIN32)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32)
+ENDIF()
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
+
+LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu)
+LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs)
+
+SET(static_mem_SRCS static-mem-allocate.c)
+SET(flash_if_SRCS flash-interface-example.c)
+ADD_EXECUTABLE(static-mem-example ${static_mem_SRCS})
+ADD_EXECUTABLE(flash-if-example ${flash_if_SRCS})
+TARGET_LINK_LIBRARIES(static-mem-example emu uffs emu platform apitest_server)
+TARGET_LINK_LIBRARIES(flash-if-example emu uffs emu platform)
+IF (UNIX)
+    TARGET_LINK_LIBRARIES(static-mem-example pthread)
+ENDIF ()
+

+ 412 - 0
components/dfs/filesystems/uffs/src/example/flash-interface-example.c

@@ -0,0 +1,412 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+/**
+ * \file flash-interface-example.c
+ * \brief example for using flash driver and multiple partitions, with static memory allocator.
+ * \author Ricky Zheng, created at 27 Nov, 2007
+ */
+  
+#include <string.h>
+#include "uffs_config.h"
+#include "uffs/uffs_os.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_flash.h"
+#include "uffs/uffs_mtb.h"
+#include "uffs/uffs_fs.h"
+
+#define PFX "ndrv: "
+
+struct my_nand_chip {
+	void *IOR_ADDR;
+	void *IOW_ADDR;
+	UBOOL inited;
+	// ... 
+};
+
+/*
+ * Standard NAND flash commands
+ */
+#define NAND_CMD_READ0		0
+#define NAND_CMD_READ1		1
+#define NAND_CMD_RNDOUT		5
+#define NAND_CMD_PAGEPROG	0x10
+#define NAND_CMD_READOOB	0x50
+#define NAND_CMD_ERASE1		0x60
+#define NAND_CMD_STATUS		0x70
+#define NAND_CMD_STATUS_MULTI	0x71
+#define NAND_CMD_SEQIN		0x80
+#define NAND_CMD_RNDIN		0x85
+#define NAND_CMD_READID		0x90
+#define NAND_CMD_ERASE2		0xd0
+#define NAND_CMD_RESET		0xff
+
+
+/* impelent the following functions for your NAND flash */
+#define CHIP_SET_CLE(chip) { chip = chip; }
+#define CHIP_CLR_CLE(chip) {}
+#define CHIP_SET_ALE(chip) {}
+#define CHIP_CLR_ALE(chip) {}
+#define CHIP_SET_NCS(chip) {}
+#define CHIP_CLR_NCS(chip) {}
+#define CHIP_BUSY(chip) {}
+#define CHIP_READY(chip) {}
+#define WRITE_COMMAND(chip, cmd) {}
+#define WRITE_DATA_ADDR(chip, block, page, offset) {}
+#define WRITE_ERASE_ADDR(chip, block) {}
+#define WRITE_DATA(chip, data, len) {}
+#define READ_DATA(chip, data, len) {}
+
+#define PARSE_STATUS(v) (UFFS_FLASH_NO_ERR)	// parse status to UFFS_FLASH_NO_ERR or UFFS_FLASH_BAD_BLK
+
+
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
+int main()
+{
+	uffs_Perror(UFFS_MSG_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
+	return 0;
+}
+#else
+
+
+static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
+						u8 *spare, int spare_len)
+{
+	u8 val = 0;
+	int ret = UFFS_FLASH_NO_ERR;
+	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
+
+	CHIP_CLR_NCS(chip);
+	if (data && data_len > 0) {
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_READ0);
+		CHIP_CLR_CLE(chip);
+		CHIP_SET_ALE(chip);
+		WRITE_DATA_ADDR(chip, block, page, 0);
+		CHIP_CLR_ALE(chip);
+		READ_DATA(chip, data, data_len);
+
+		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
+		memset(data, 0xFF, data_len);
+	}
+
+	if (spare && spare_len > 0) {
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_READOOB);
+		CHIP_CLR_CLE(chip);
+		CHIP_SET_ALE(chip);
+		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
+		CHIP_CLR_ALE(chip);
+		READ_DATA(chip, spare, spare_len);
+
+		// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
+		memset(spare, 0xFF, spare_len);
+	}
+
+	if (data == NULL && spare == NULL) {
+		// read bad block mark
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_READOOB);
+		CHIP_CLR_CLE(chip);
+		CHIP_SET_ALE(chip);
+		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
+		CHIP_CLR_ALE(chip);
+		READ_DATA(chip, &val, 1);
+		ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
+
+		// for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver
+		ret = UFFS_FLASH_NO_ERR;
+	}
+
+	CHIP_SET_NCS(chip);
+
+	return ret;
+}
+
+static int nand_write_page(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *spare, int spare_len)
+{
+	u8 val = 0;
+	int ret = UFFS_FLASH_NO_ERR;
+	UBOOL fall_through = FALSE;
+	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
+
+	CHIP_CLR_NCS(chip);
+
+	if (data && data_len > 0) {
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_READ0);
+		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
+		CHIP_CLR_CLE(chip);
+		CHIP_SET_ALE(chip);
+		WRITE_DATA_ADDR(chip, block, page, 0);
+		CHIP_CLR_ALE(chip);
+		CHIP_BUSY(chip);
+		WRITE_DATA(chip, data, data_len);
+		if (data_len == dev->attr->page_data_size)
+			fall_through = U_TRUE;
+		else {
+			CHIP_SET_CLE(chip);
+			WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
+			WRITE_COMMAND(chip, NAND_CMD_STATUS);
+			CHIP_CLR_CLE(chip);
+			CHIP_READY(chip);
+			READ_DATA(chip, &val, 1);
+			ret = PARSE_STATUS(val);
+		}
+	}
+
+	if (ret != UFFS_FLASH_NO_ERR)
+		goto ext;
+
+	if (spare && spare_len > 0) {
+		if (!fall_through) {
+			CHIP_SET_CLE(chip);
+			WRITE_COMMAND(chip, NAND_CMD_READOOB);
+			WRITE_COMMAND(chip, NAND_CMD_SEQIN);
+			CHIP_CLR_CLE(chip);
+			CHIP_SET_ALE(chip);
+			WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
+			CHIP_CLR_ALE(chip);
+			CHIP_BUSY(chip);
+		}
+		WRITE_DATA(chip, spare, spare_len);
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
+		WRITE_COMMAND(chip, NAND_CMD_STATUS);
+		CHIP_CLR_CLE(chip);
+		CHIP_READY(chip);
+		READ_DATA(chip, &val, 1);
+		ret = PARSE_STATUS(val);
+	}
+
+	if (data == NULL && spare == NULL) {
+		// mark bad block
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_READOOB);
+		WRITE_COMMAND(chip, NAND_CMD_SEQIN);
+		CHIP_CLR_CLE(chip);
+		CHIP_SET_ALE(chip);
+		WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
+		CHIP_CLR_ALE(chip);
+		CHIP_BUSY(chip);
+		val = 0;
+		WRITE_DATA(chip, &val, 1);
+		CHIP_SET_CLE(chip);
+		WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
+		WRITE_COMMAND(chip, NAND_CMD_STATUS);
+		CHIP_CLR_CLE(chip);
+		CHIP_READY(chip);
+		READ_DATA(chip, &val, 1);
+		ret = PARSE_STATUS(val);
+	}
+
+ext:
+	CHIP_SET_NCS(chip);
+
+	return ret;
+}
+
+static int nand_erase_block(uffs_Device *dev, u32 block)
+{
+	u8 val = 0;
+	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
+
+	CHIP_CLR_NCS(chip);
+
+	CHIP_SET_CLE(chip);
+	WRITE_COMMAND(chip, NAND_CMD_ERASE1);
+	CHIP_CLR_CLE(chip);
+	CHIP_SET_ALE(chip);
+	WRITE_ERASE_ADDR(chip, blcok);
+	CHIP_CLR_ALE(chip);
+	CHIP_SET_CLE(chip);
+	WRITE_COMMAND(chip, NAND_CMD_ERASE2);
+	WRITE_COMMAND(chip, NAND_CMD_STATUS);
+	CHIP_CLR_CLE(chip);
+	CHIP_READY(chip);
+	READ_DATA(chip, &val, 1);
+
+	CHIP_SET_NCS(chip);
+
+	val = val; // just for eliminating warning
+
+	return PARSE_STATUS(val);
+}
+
+
+static int nand_init_flash(uffs_Device *dev)
+{
+	// initialize your hardware here ...
+	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
+
+	if (!chip->inited) {
+		// setup chip I/O address, setup NAND flash controller ... etc.
+		// chip->IOR_ADDR = 0xF0000000
+		// chip->IOW_ADDR = 0xF0000000
+		chip->inited = U_TRUE;
+	}
+	return 0;
+}
+
+static int nand_release_flash(uffs_Device *dev)
+{
+	// release your hardware here
+	struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
+
+	chip = chip;
+
+	return 0;
+}
+
+static uffs_FlashOps g_my_nand_ops = {
+	nand_init_flash,	// InitFlash()
+	nand_release_flash,	// ReleaseFlash()
+	nand_read_page,		// ReadPage()
+	NULL,				// ReadPageWithLayout
+	nand_write_page,	// WritePage()
+	NULL,				// WirtePageWithLayout
+	NULL,				// IsBadBlock(), let UFFS take care of it.
+	NULL,				// MarkBadBlock(), let UFFS take care of it.
+	nand_erase_block,	// EraseBlock()
+};
+
+/////////////////////////////////////////////////////////////////////////////////
+
+// change these parameters to fit your nand flash specification
+
+#define TOTAL_BLOCKS    1024
+#define PAGE_DATA_SIZE  512
+#define PAGE_SPARE_SIZE 16
+#define PAGES_PER_BLOCK 32
+#define PAGE_SIZE		(PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
+#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK)
+
+#define NR_PARTITION	2								/* total partitions */
+#define PAR_1_BLOCKS	100								/* partition 1 */
+#define PAR_2_BLOCKS	(TOTAL_BLOCKS - PAR_1_BLOCKS)	/* partition 2 */
+
+struct my_nand_chip g_nand_chip = {0};
+static struct uffs_StorageAttrSt g_my_flash_storage = {0};
+
+/* define mount table */
+static uffs_Device demo_device_1 = {0};
+static uffs_Device demo_device_2 = {0};
+
+static uffs_MountTable demo_mount_table[] = {
+	{ &demo_device_1,  0, PAR_1_BLOCKS - 1, "/data/" },
+	{ &demo_device_2,  PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" },
+	{ NULL, 0, 0, NULL }
+};
+
+/* static alloc the memory for each partition */
+static int static_buffer_par1[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_1_BLOCKS) / sizeof(int)];
+static int static_buffer_par2[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_2_BLOCKS) / sizeof(int)];;
+
+static void init_nand_chip(struct my_nand_chip *chip)
+{
+	// init chip IO address, etc.
+}
+
+static void setup_flash_storage(struct uffs_StorageAttrSt *attr)
+{
+	memset(attr, 0, sizeof(struct uffs_StorageAttrSt));
+	
+	// setup NAND flash attributes.	
+	attr->total_blocks = TOTAL_BLOCKS;			/* total blocks */
+	attr->page_data_size = PAGE_DATA_SIZE;		/* page data size */
+	attr->pages_per_block = PAGES_PER_BLOCK;	/* pages per block */
+	attr->spare_size = PAGE_SPARE_SIZE;		  	/* page spare size */
+	attr->block_status_offs = 4;				/* block status offset is 5th byte in spare */
+	attr->ecc_opt = UFFS_ECC_SOFT;              /* ecc option */
+	attr->layout_opt = UFFS_LAYOUT_UFFS;        /* let UFFS do the spare layout */    
+}
+
+static URET my_InitDevice(uffs_Device *dev)
+{
+	dev->attr = &g_my_flash_storage;			// NAND flash attributes
+	dev->attr->_private = (void *) &g_nand_chip;// hook nand_chip data structure to attr->_private
+	dev->ops = &g_my_nand_ops;					// NAND driver
+
+	init_nand_chip(&g_nand_chip);
+    
+	return U_SUCC;
+}
+
+static URET my_ReleaseDevice(uffs_Device *dev)
+{
+	return U_SUCC;
+}
+
+
+static int my_init_filesystem(void)
+{
+	uffs_MountTable *mtbl = &(demo_mount_table[0]);
+
+	/* setup nand storage attributes */
+	setup_flash_storage(&g_my_flash_storage);
+
+	/* setup memory allocator */
+	uffs_MemSetupStaticAllocator(&demo_device_1.mem, static_buffer_par1, sizeof(static_buffer_par1));
+	uffs_MemSetupStaticAllocator(&demo_device_2.mem, static_buffer_par2, sizeof(static_buffer_par2));
+
+	/* register mount table */
+	while(mtbl->dev) {
+		// setup device init/release entry
+		mtbl->dev->Init = my_InitDevice;
+		mtbl->dev->Release = my_ReleaseDevice;
+		uffs_RegisterMountTable(mtbl);
+		mtbl++;
+	}
+	
+	return uffs_InitMountTable() == U_SUCC ? 0 : -1;
+}
+
+/* application entry */
+int main()
+{
+	uffs_SetupDebugOutput(); 	// setup debug output as early as possible
+
+	my_init_filesystem();
+
+	// ... my application codes ....
+	// read/write/create/delete files ...
+
+	uffs_ReleaseMountTable();
+
+	return 0;
+}
+
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////////

+ 158 - 0
components/dfs/filesystems/uffs/src/example/static-mem-allocate.c

@@ -0,0 +1,158 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file static-mem-allocate.c
+ * \brief demostrate how to use static memory allocation. This example use 
+ *        file emulated NAND flash, one partition only.
+ * \author Ricky Zheng
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "uffs_config.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_fs.h"
+#include "uffs/uffs_utils.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_mtb.h"
+#include "cmdline.h"
+#include "uffs_fileem.h"
+
+#define PFX "sexp: "
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
+int main()
+{
+	uffs_Perror(UFFS_MSG_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
+	return 0;
+}
+#else
+
+extern struct cli_commandset * get_helper_cmds(void);
+extern struct cli_commandset * get_test_cmds(void);
+
+#define PAGE_DATA_SIZE    512
+#define PAGE_SPARE_SIZE   16
+#define PAGES_PER_BLOCK   32
+#define TOTAL_BLOCKS      128
+
+#define PAGE_SIZE					(PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
+#define BLOCK_DATA_SIZE				(PAGES_PER_BLOCK * PAGE_DATA_SIZE)
+#define TOTAL_DATA_SIZE				(TOTAL_BLOCKS * BLOCK_DATA_SIZE)
+#define BLOCK_SIZE					(PAGES_PER_BLOCK * PAGE_SIZE)
+#define TOTAL_SIZE					(BLOCK_SIZE * TOTAL_BLOCKS)
+
+#define MAX_MOUNT_TABLES		10
+#define MAX_MOUNT_POINT_NAME	32
+
+static uffs_Device demo_device = {0};
+static struct uffs_MountTableEntrySt demo_mount = {
+	&demo_device,
+	0,    /* start from block 0 */
+	-1,   /* use whole chip */
+	"/",  /* mount point */
+	NULL
+};
+
+/* static alloc the memory */
+static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)];
+
+
+static void setup_storage(struct uffs_StorageAttrSt *attr)
+{
+	attr->total_blocks = TOTAL_BLOCKS;			/* total blocks */
+	attr->page_data_size = PAGE_DATA_SIZE;		/* page data size */
+	attr->spare_size = PAGE_SPARE_SIZE;		  	/* page spare size */
+	attr->pages_per_block = PAGES_PER_BLOCK;	/* pages per block */
+	attr->block_status_offs = 4;				/* block status offset is 5th byte in spare */
+    attr->ecc_opt = UFFS_ECC_SOFT;              /* use UFFS software ecc */
+    attr->layout_opt = UFFS_LAYOUT_UFFS;        /* let UFFS do the spare layout */    
+}
+
+static void setup_device(uffs_Device *dev)
+{
+	// using file emulator device
+	dev->Init = femu_InitDevice;
+	dev->Release = femu_ReleaseDevice;
+	dev->attr = femu_GetStorage();
+}
+
+static int init_uffs_fs(void)
+{
+	struct uffs_MountTableEntrySt *mtbl = &demo_mount;
+
+	/* setup flash storage attributes */
+	setup_storage(femu_GetStorage());
+
+	/* setup memory allocator */
+	uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool));
+
+	/* setup device: init, release, attr */
+	setup_device(mtbl->dev);
+
+	/* register mount table */
+	uffs_RegisterMountTable(mtbl);
+
+	return uffs_InitMountTable() == U_SUCC ? 0 : -1;
+}
+
+static int release_uffs_fs(void)
+{
+	return uffs_ReleaseMountTable();
+}
+
+int main(int argc, char *argv[])
+{
+	int ret;
+
+	uffs_SetupDebugOutput(); 	// setup debug output as early as possible
+
+	ret = init_uffs_fs();
+
+	if (ret != 0) {
+		printf ("Init file system fail: %d\n", ret);
+		return -1;
+	}
+
+	cli_add_commandset(get_helper_cmds());
+	cli_add_commandset(get_test_cmds());
+	cli_main_entry();
+
+	release_uffs_fs();
+
+	return 0;
+}
+
+#endif
+

+ 101 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs.h

@@ -0,0 +1,101 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+/** 
+ * \file uffs.h
+ * \brief uffs basic defines
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_H_
+#define _UFFS_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define UO_RDONLY		0x0000		/** read only */
+#define UO_WRONLY		0x0001		/** write only */
+#define UO_RDWR			0x0002		/** read and write */
+#define UO_APPEND		0x0008		/** append */
+
+#define UO_BINARY		0x0000		/** no used in uffs */
+
+#define UO_CREATE		0x0100
+#define UO_TRUNC		0x0200
+#define UO_EXCL			0x0400
+
+#define UO_NOECC		0x0800		/** skip ECC when reading file data from media */
+
+
+#define UO_DIR			0x1000		/** open a directory */
+
+
+
+#define UENOERR 0		/** no error */
+#define UEACCES	1		/** Tried to open read-only file
+						 for writing, or files sharing mode
+						 does not allow specified operations,
+						 or given path is directory */
+
+#define UEEXIST	2		/** _O_CREAT and _O_EXCL flags specified,
+							but filename already exists */
+#define UEINVAL	3		/** Invalid oflag or pmode argument */
+#define UEMFILE	4		/** No more file handles available
+						  (too many open files)  */
+#define UENOENT	5		/** file or path not found */
+#define UETIME	6		/** can't set file time */
+#define UEBADF	9		/** invalid file handle */
+#define UENOMEM	10		/** no enough memory */
+#define UEIOERR	11		/** I/O error from lower level flash operation */
+#define UENOTDIR 12		/** Not a directory */
+#define UEISDIR 13		/** Is a directory */    
+
+#define UEUNKNOWN_ERR	100	/** unknown error */
+
+
+
+#define _SEEK_CUR		0		/** seek from current position */
+#define _SEEK_SET		1		/** seek from beginning of file */
+#define _SEEK_END		2		/** seek from end of file */
+
+#define USEEK_CUR		_SEEK_CUR
+#define USEEK_SET		_SEEK_SET
+#define USEEK_END		_SEEK_END
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 75 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_badblock.h

@@ -0,0 +1,75 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+/** 
+ * \file uffs_badblock.h
+ * \brief bad block management
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_BADBLOCK_H_
+#define _UFFS_BADBLOCK_H_
+
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#define HAVE_BADBLOCK(dev) (dev->bad.block != UFFS_INVALID_BLOCK)
+
+/** initialize bad block management data structures for uffs device */
+void uffs_BadBlockInit(uffs_Device *dev);
+
+/** processing bad block: erase bad block,
+	mark it as 'bad' and put it to bad block list */
+void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node);
+
+/** processing bad block: erase bad block,
+	mark it as 'bad' and put it to suspend block list */
+void uffs_BadBlockProcessSuspend(uffs_Device *dev, TreeNode *node);
+
+/** try to recover data from a new discovered bad block */
+void uffs_BadBlockRecover(uffs_Device *dev);
+
+/** put a new block to the bad block waiting list */
+void uffs_BadBlockAdd(uffs_Device *dev, int block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 107 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_blockinfo.h

@@ -0,0 +1,107 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+/** 
+ * \file uffs_blockinfo.h
+ * \brief data structure for operating block information
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_BLOCKINFO_H_
+#define _UFFS_BLOCKINFO_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+/** 
+ * \struct uffs_PageSpareSt
+ * \brief this structure is for storing uffs tag and more. 
+ */
+struct uffs_PageSpareSt {
+	uffs_Tags tag;			//!< page tag
+	int expired:1;
+};
+
+/** 
+ * \struct uffs_BlockInfoSt
+ * \brief block information data. Block info is frequently accessed,
+          UFFS use a cache system to speed up block info access.
+ */
+struct uffs_BlockInfoSt {
+	struct uffs_BlockInfoSt *next;
+	struct uffs_BlockInfoSt *prev;
+	u16 block;							//!< block number
+	struct uffs_PageSpareSt *spares;	//!< page spare info array
+	int expired_count;					//!< how many pages expired in this block ? 
+	int ref_count;						//!< reference counter, it's safe to reuse this block memory when the counter is 0.
+};
+
+/** get tag from block info */
+#define GET_TAG(bc, page) (&(bc)->spares[page].tag)
+
+
+/** initialize block info caches */
+URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks);
+
+/** release block info caches */
+URET uffs_BlockInfoReleaseCache(uffs_Device *dev);
+
+/** load page spare to block info cache */
+URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page);
+
+/** find block info cache */
+uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block);
+
+/** get block info cache, load it on demand */
+uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block);
+
+/** put info cache back to pool, should be called with #uffs_BlockInfoGet in pairs. */
+void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p);
+
+/** explicitly expire a block info cache */
+void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page);
+
+/** no one hold any block info cache ? safe to release block info caches */
+UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev);
+
+/** explicitly expire all block info caches */
+void uffs_BlockInfoExpireAll(uffs_Device *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 178 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h

@@ -0,0 +1,178 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_buf.h
+ * \brief page buffers
+ * \author Ricky Zheng
+ */
+
+#ifndef UFFS_BUF_H
+#define UFFS_BUF_H
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_tree.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+	
+#define CLONE_BUF_MARK		0xffff		//!< set uffs_BufSt::ref_count to this for a 'cloned' buffer
+
+/** for uffs_BufSt::mark */
+#define UFFS_BUF_EMPTY		0			//!< buffer is empty
+#define UFFS_BUF_VALID		1			//!< buffer is holding valid data
+#define UFFS_BUF_DIRTY		2			//!< buffer data is modified
+
+/** for uffs_BufSt::ext_mark */
+#define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1	//!< the last page of file (when truncating a file)
+
+/** uffs page buffer */
+struct uffs_BufSt{
+	struct uffs_BufSt *next;			//!< link to next buffer
+	struct uffs_BufSt *prev;			//!< link to previous buffer
+	struct uffs_BufSt *next_dirty;		//!< link to next dirty buffer
+	struct uffs_BufSt *prev_dirty;		//!< link to previous dirty buffer
+	u8 type;							//!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA
+	u8 ext_mark;						//!< extension mark. 
+	u16 parent;							//!< parent serial
+	u16 serial;							//!< serial 
+	u16 page_id;						//!< page id 
+	u16 mark;							//!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ?
+	u16 ref_count;						//!< reference counter, or #CLONE_BUF_MARK for a cloned buffer
+	u16 data_len;						//!< length of data
+	u16 check_sum;						//!< checksum field
+	u8 * data;							//!< data buffer
+	u8 * header;						//!< header
+};
+
+#define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE)
+
+/** initialize page buffers */
+URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max);
+
+/** release page buffers */
+URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev);
+
+/** find the page buffer, move to link list head if found */
+uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id);
+uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id, int oflag);
+
+/** alloc a new page buffer */
+uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id);
+
+/** find the page buffer (not affect the reference counter) */
+uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id);
+
+/** find the page buffer from #start (not affect the reference counter) */
+uffs_Buf * uffs_BufFindFrom(uffs_Device *dev, uffs_Buf *start,
+						u16 parent, u16 serial, u16 page_id);
+
+/** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */
+URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf);
+
+/** increase buffer references */
+void uffs_BufIncRef(uffs_Buf *buf);
+
+/** decrease buffer references */
+void uffs_BufDecRef(uffs_Buf *buf);
+
+/** write data to a page buffer */
+URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
+
+/** read data from a page buffer */
+URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
+
+/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */
+void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf);
+
+/** if there is no free dirty group slot, flush the most dirty group */
+URET uffs_BufFlush(struct uffs_DeviceSt *dev);
+URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover);
+
+/** flush dirty group */
+URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
+URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover);
+
+/** find free dirty group slot */
+int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev);
+
+/** find the dirty group slot */
+int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
+
+/** lock dirty group */
+URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot);
+
+/** unlock dirty group */
+URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot);
+
+/** flush most dirty group */
+URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev);
+
+/** flush all groups under the same parent number */
+URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent);
+
+/** flush all page buffers */
+URET uffs_BufFlushAll(struct uffs_DeviceSt *dev);
+
+/** no one holding any page buffer ? safe to release page buffers */
+UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev);
+
+/** are all page buffer marked with #UFFS_BUF_EMPTY ? */
+UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev);
+
+/** mark all page buffer as #UFFS_BUF_EMPTY */
+URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev);
+
+/** clone a page buffer */
+uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf);
+
+/** release a cloned page buffer, call in pair with #uffs_BufClone */
+URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf);
+
+/** load physical storage data to page buffer */
+URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
+
+/** load physical storage data to page buffer withouth checking ECC */
+URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
+
+/** showing page buffers info, for debug only */
+void uffs_BufInspect(uffs_Device *dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

+ 59 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_core.h

@@ -0,0 +1,59 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_CORE_H_
+#define _UFFS_CORE_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/** \typedef uffs_Device */
+typedef struct uffs_DeviceSt		uffs_Device;
+/** \typedef uffs_FlashOps */
+typedef struct uffs_FlashOpsSt		uffs_FlashOps;
+
+typedef struct uffs_BlockInfoSt uffs_BlockInfo;
+typedef struct uffs_PageSpareSt uffs_PageSpare;
+typedef struct uffs_TagsSt			uffs_Tags;		//!< UFFS page tags
+typedef struct uffs_TagStoreSt      uffs_TagStore;  //!< UFFS page tags physical store structure
+
+typedef struct uffs_BufSt uffs_Buf;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif

+ 46 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_crc.h

@@ -0,0 +1,46 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_crc.h
+ * \author Ricky Zheng, created 23 Nov, 2011
+ */
+
+#ifndef _UFFS_CRC_H_
+#define _UFFS_CRC_H_
+
+#include "uffs/uffs_types.h"
+
+u16 uffs_crc16update(const void *data, int length, u16 crc);
+u16 uffs_crc16sum(const void *data, int length);
+
+#endif

+ 211 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_device.h

@@ -0,0 +1,211 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_device.h
+ * \brief uffs device structures definition
+ * \author Ricky Zheng
+ */
+
+#ifndef UFFS_DEVICE_H
+#define UFFS_DEVICE_H
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_buf.h"
+#include "uffs/uffs_blockinfo.h"
+#include "uffs/uffs_pool.h"
+#include "uffs/uffs_tree.h"
+#include "uffs/uffs_mem.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_flash.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/**
+ * \def MAX_DIRTY_BUF_GROUPS
+ */
+#define MAX_DIRTY_BUF_GROUPS    3
+
+
+/** 
+ * \struct uffs_BlockInfoCacheSt
+ * \brief block information structure, used to manager block information caches
+ */
+struct uffs_BlockInfoCacheSt {
+	uffs_BlockInfo *head;			//!< buffer head of block info(spares)
+	uffs_BlockInfo *tail;			//!< buffer tail
+	void *mem_pool;					//!< internal memory pool, used for release whole buffer
+};
+
+/** 
+ * \struct uffs_PartitionSt
+ * \brief partition basic information
+ */
+struct uffs_PartitionSt {
+	u16 start;		//!< start block number of partition
+	u16 end;		//!< end block number of partition
+};
+
+/** 
+ * \struct uffs_LockSt
+ * \brief lock stuffs
+ */
+struct uffs_LockSt {
+	OSSEM sem;
+	int task_id;
+	int counter;
+};
+
+/** 
+ * \struct uffs_DirtyGroupSt
+ * \brief manager dirty page buffers
+ */
+struct uffs_DirtyGroupSt {
+	int count;					//!< dirty buffers count
+	int lock;					//!< dirty group lock (0: unlocked, >0: locked)
+	uffs_Buf *dirty;			//!< dirty buffer list
+};
+
+/** 
+ * \struct uffs_PageBufDescSt
+ * \brief uffs page buffers descriptor
+ */
+struct uffs_PageBufDescSt {
+	uffs_Buf *head;			//!< head of buffers
+	uffs_Buf *tail;			//!< tail of buffers
+	struct uffs_DirtyGroupSt dirtyGroup[MAX_DIRTY_BUF_GROUPS];	//!< dirty buffer groups
+	int buf_max;			//!< maximum buffers
+	int dirty_buf_max;		//!< maximum dirty buffer allowed
+	void *pool;				//!< memory pool for buffers
+};
+
+
+/** 
+ * \struct uffs_PageCommInfoSt
+ * \brief common data for device, should be initialised at early
+ * \note it is possible that pg_size is smaller than physical page size, but normally they are the same.
+ * \note page data layout: [HEADER] + [DATA]
+ */
+struct uffs_PageCommInfoSt {
+	u16 pg_data_size;			//!< page data size
+	u16 header_size;			//!< header size
+	u16 pg_size;				//!< page size
+};
+
+/** 
+ * \struct uffs_NewBadBlockSt
+ * \brief holding new discovered bad block
+ */
+struct uffs_NewBadBlockSt {
+	u16 block;				//!< bad block, FIX ME to process more than one bad block
+};
+
+/**
+ * \struct uffs_FlashStatSt
+ * \typedef uffs_FlashStat
+ * \brief statistic data of flash read/write/erase activities
+ */
+typedef struct uffs_FlashStatSt {
+	int block_erase_count;
+	int page_write_count;
+	int page_read_count;
+	int page_header_read_count;
+	int spare_write_count;
+	int spare_read_count;
+	unsigned long io_read;
+	unsigned long io_write;
+} uffs_FlashStat;
+
+
+/**
+ * \struct uffs_ConfigSt
+ * \typedef uffs_Config
+ * \brief uffs config parameters
+ */
+typedef struct uffs_ConfigSt {
+	int bc_caches;
+	int page_buffers;
+	int dirty_pages;
+	int dirty_groups;
+	int reserved_free_blocks;
+} uffs_Config;
+
+
+/** 
+ * \struct uffs_DeviceSt
+ * \brief The core data structure of UFFS, all information needed by manipulate UFFS object
+ * \note one partition corresponding one uffs device.
+ */
+struct uffs_DeviceSt {
+	URET (*Init)(uffs_Device *dev);				//!< low level initialisation
+	URET (*Release)(uffs_Device *dev);			//!< low level release
+	void *_private;								//!< private data for device
+
+	struct uffs_StorageAttrSt		*attr;		//!< storage attribute
+	struct uffs_PartitionSt			par;		//!< partition information
+	struct uffs_FlashOpsSt			*ops;		//!< flash operations
+	struct uffs_BlockInfoCacheSt	bc;			//!< block info cache
+	struct uffs_LockSt				lock;		//!< lock data structure
+	struct uffs_PageBufDescSt		buf;		//!< page buffers
+	struct uffs_PageCommInfoSt		com;		//!< common information
+	struct uffs_TreeSt				tree;		//!< tree list of block
+	struct uffs_NewBadBlockSt		bad;		//!< new discovered bad block
+	struct uffs_FlashStatSt			st;			//!< statistic (counters)
+	struct uffs_memAllocatorSt		mem;		//!< uffs memory allocator
+	struct uffs_ConfigSt			cfg;		//!< uffs config
+	u32	ref_count;								//!< device reference count
+	int	dev_num;								//!< device number (partition number)	
+};
+
+
+/** create the lock for uffs device */
+void uffs_DeviceInitLock(uffs_Device *dev);
+
+/** delete the lock of uffs device */
+void uffs_DeviceReleaseLock(uffs_Device *dev);
+
+/** lock uffs device */
+void uffs_DeviceLock(uffs_Device *dev);
+
+/** unlock uffs device */
+void uffs_DeviceUnLock(uffs_Device *dev);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 89 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_ecc.h

@@ -0,0 +1,89 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_ecc.h
+ * \brief file handle operations
+ * \author Ricky Zheng, created 8th Jun, 2005
+ */
+
+#ifndef _UFFS_ECC_H_
+#define _UFFS_ECC_H_
+
+#include <string.h>
+
+#include "uffs/uffs_fs.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+
+#define MAX_ECC_LENGTH	24	//!< 2K page ecc length is 24 bytes.
+
+/**
+ * calculate ECC
+ * \return length of generated ECC. (3 bytes ECC per 256 data) 
+ */
+int uffs_EccMake(const void *data, int data_len, void *ecc);
+
+/** 
+ * correct data by ECC.
+ *
+ * return:   0 -- no error
+ *			-1 -- can not be corrected
+ *			>0 -- how many bits are corrected
+ */
+int uffs_EccCorrect(void *data, int data_len, void *read_ecc, const void *test_ecc);
+
+
+/**
+ * generate 12 bit ecc for maximum 8 bytes data
+ */
+u16 uffs_EccMake8(const void *data, int data_len);
+
+/**
+ * correct maximum 8 bytes data from 12 bits ECC
+ *
+ * return:   0 -- no error
+ *			-1 -- can not be corrected
+ *			>0 -- how many bits are corrected
+ */
+int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 151 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_fd.h

@@ -0,0 +1,151 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_fd.h
+ * \brief PISIX like file operations
+ * \author Ricky Zheng, created 8th Jun, 2005
+ */
+
+#ifndef _UFFS_FD_H_
+#define _UFFS_FD_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#include "uffs/uffs.h"
+
+/**
+ * \brief definitions for uffs_stat::st_mode
+ */
+#define	US_IFMT		0xF000	/* file type make */
+#define	US_IFREG	0x8000	/* regular */
+#define	US_IFLNK	0xA000	/* symbolic link */
+#define	US_IFDIR	0x4000	/* directory */
+#define	US_IREAD	0000400	/* read permission */
+#define	US_IWRITE	0000200	/* write permission */
+
+#define	US_IRWXU	00700	/* RWX	owner */
+#define	US_IRUSR	00400	/* R	owner */
+#define	US_IWUSR	00200	/* W	owner */
+#define	US_IXUSR	00100	/* X	owner */
+#define	US_IRWXG	00070	/* RWX	group */
+#define	US_IRGRP	00040	/* R	group */
+#define	US_IWGRP	00020	/* W	group */
+#define	US_IXGRP	00010	/* X	group */
+#define	US_IRWXO	00007	/* RWX	other */
+#define	US_IROTH	00004	/* R	other */
+#define	US_IWOTH	00002	/* W	other */
+#define	US_IXOTH	00001	/* X	other */
+
+/**
+ * \brief POSIX dirent
+ */
+struct uffs_dirent {
+    int d_ino;							/* inode number (serial number of this object) */
+    int d_off;							/* offset to this dirent */
+    unsigned short int d_reclen;		/* length of this uffs_dirent */
+    unsigned short int d_namelen;		/* length of this d_name */
+    unsigned char d_type;				/* type of this record */
+    char d_name[256];					/* name of this object */
+};
+
+struct uffs_dirSt;
+typedef struct uffs_dirSt uffs_DIR;
+
+/**
+ * \brief POSIX stat
+ */
+struct uffs_stat {
+    int			st_dev;     /* ID of device containing file */
+    int			st_ino;     /* inode number */
+    int			st_mode;    /* protection */
+    int			st_nlink;   /* number of hard links */
+    int			st_uid;     /* user ID of owner */
+    int			st_gid;     /* group ID of owner */
+    int			st_rdev;    /* device ID (if special file) */
+    long		st_size;    /* total size, in bytes */
+    int			st_blksize; /* blocksize for filesystem I/O */
+    int			st_blocks;  /* number of blocks allocated */
+    unsigned int	st_atime;   /* time of last access */
+    unsigned int	st_mtime;   /* time of last modification */
+    unsigned int	st_ctime;   /* time of last status change */
+};
+
+/* POSIX complaint file system APIs */
+
+int uffs_open(const char *name, int oflag, ...);
+int uffs_close(int fd);
+int uffs_read(int fd, void *data, int len);
+int uffs_write(int fd, const void *data, int len);
+long uffs_seek(int fd, long offset, int origin);
+long uffs_tell(int fd);
+int uffs_eof(int fd);
+int uffs_flush(int fd);
+int uffs_rename(const char *old_name, const char *new_name);
+int uffs_remove(const char *name);
+int uffs_ftruncate(int fd, long remain);
+
+int uffs_mkdir(const char *name, ...);
+int uffs_rmdir(const char *name);
+
+int uffs_stat(const char *name, struct uffs_stat *buf);
+int uffs_lstat(const char *name, struct uffs_stat *buf);
+int uffs_fstat(int fd, struct uffs_stat *buf);
+
+int uffs_closedir(uffs_DIR *dirp);
+uffs_DIR * uffs_opendir(const char *path);
+struct uffs_dirent * uffs_readdir(uffs_DIR *dirp);
+
+void uffs_rewinddir(uffs_DIR *dirp);
+
+
+int uffs_get_error(void);
+int uffs_set_error(int err);
+
+int uffs_version(void);
+int uffs_format(const char *mount_point);
+
+long uffs_space_total(const char *mount_point);
+long uffs_space_used(const char *mount_point);
+long uffs_space_free(const char *mount_point);
+
+void uffs_flush_all(const char *mount_point);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+

+ 76 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_find.h

@@ -0,0 +1,76 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_find.h
+ * \brief find objects under dir
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_FIND_H_
+#define _UFFS_FIND_H_
+
+#include "uffs/uffs_fs.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+typedef struct uffs_FindInfoSt {
+	uffs_Device *dev;				//!< the device to be searched
+	u16 serial;						//!< the dir serial number
+	int step;						//!< step:	0 - working on dir entries,
+									//			1 - working on file entries,
+									//			2 - stoped.
+	int hash;						//!< hash entry, internal used
+	TreeNode *work;					//!< working node, internal used.
+	int pos;						//!< current position
+} uffs_FindInfo;
+
+
+URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err);
+URET uffs_FindObjectOpen(uffs_FindInfo *find_handle, uffs_Object *dir);
+URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir);
+URET uffs_FindObjectFirst(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
+URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
+URET uffs_FindObjectRewind(uffs_FindInfo *find_handle);
+URET uffs_FindObjectClose(uffs_FindInfo * find_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+

+ 311 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_flash.h

@@ -0,0 +1,311 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_public.h
+ * \brief flash interface for UFFS
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_FLASH_H_
+#define _UFFS_FLASH_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_fs.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+/** ECC options (uffs_StorageAttrSt.ecc_opt) */
+#define UFFS_ECC_NONE		0	//!< do not use ECC
+#define UFFS_ECC_SOFT		1	//!< UFFS calculate the ECC
+#define UFFS_ECC_HW			2	//!< Flash driver(or by hardware) calculate the ECC
+#define UFFS_ECC_HW_AUTO	3	//!< Hardware calculate the ECC and automatically write to spare.
+
+#define UFFS_ECC_OPTION_STRING \
+	{ "none", "soft", "hw", "auto" }	// index is the ecc option value.
+
+/** spare layout options (uffs_StorageAttrSt.layout_opt) */
+#define UFFS_LAYOUT_UFFS	0	//!< do layout by dev->attr information
+#define UFFS_LAYOUT_FLASH	1	//!< flash driver do the layout
+
+#define UFFS_SPARE_LAYOUT_SIZE	6	//!< maximum spare layout array size, 2 segments
+
+/** flash operation return code */
+#define UFFS_FLASH_NO_ERR		0		//!< no error
+#define UFFS_FLASH_ECC_OK		1		//!< bit-flip found, but corrected by ECC
+#define UFFS_FLASH_NOT_SEALED	2		//!< page spare area is not sealed properly (only for ReadPageWithLayout())
+#define UFFS_FLASH_IO_ERR		-1		//!< I/O error
+#define UFFS_FLASH_ECC_FAIL		-2		//!< ECC failed
+#define UFFS_FLASH_BAD_BLK		-3		//!< bad block
+#define UFFS_FLASH_CRC_ERR		-4		//!< CRC failed
+#define UFFS_FLASH_UNKNOWN_ERR	-100	//!< unkown error?
+
+#define UFFS_FLASH_HAVE_ERR(e)		((e) < 0)
+
+#if defined(CONFIG_BAD_BLOCK_POLICY_STRICT)
+# define UFFS_FLASH_IS_BAD_BLOCK(e)	\
+	((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_ECC_OK || (e) == UFFS_FLASH_BAD_BLK || (e) == UFFS_FLASH_CRC_ERR)
+#else
+# define UFFS_FLASH_IS_BAD_BLOCK(e)	\
+	((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_BAD_BLK || (e) == UFFS_FLASH_CRC_ERR)
+#endif
+
+
+/** defines for page info (data length and data sum) */
+#define UFFS_PAGE_INFO_CLEAN	0xFFFFFFFF
+#define UFFS_PAGE_INFO_IOERR	0xDEADFFFF
+#define UFFS_PAGE_GET_LEN(info)	(info & 0xFFFF)
+#define UFFS_PAGE_GET_DSUM(info) (info >> 16)
+#define UFFS_PAGE_MAKE_INFO(d_len, d_sum) ((d_sum << 16) | d_len)
+
+/** 
+ * \struct uffs_StorageAttrSt
+ * \brief uffs device storage attribute, provide by nand specific file
+ */
+struct uffs_StorageAttrSt {
+	u32 total_blocks;		//!< total blocks in this chip
+	u16 page_data_size;		//!< page data size (physical page data size, e.g. 512)
+	u16 pages_per_block;	//!< pages per block
+	u8 spare_size;			//!< page spare size (physical page spare size, e.g. 16)
+	u8 block_status_offs;	//!< block status byte offset in spare
+	int ecc_opt;			//!< ecc option ( #UFFS_ECC_[NONE|SOFT|HW|HW_AUTO] )
+	int layout_opt;			//!< layout option (#UFFS_LAYOUT_UFFS or #UFFS_LAYOUT_FLASH)
+	int ecc_size;			//!< ecc size in bytes
+	const u8 *ecc_layout;	//!< page data ECC layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
+	const u8 *data_layout;	//!< spare data layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
+	u8 _uffs_ecc_layout[UFFS_SPARE_LAYOUT_SIZE];	//!< uffs spare ecc layout
+	u8 _uffs_data_layout[UFFS_SPARE_LAYOUT_SIZE];	//!< uffs spare data layout
+	void *_private;			//!< private data for storage attribute
+};
+
+
+/**
+ * \struct uffs_FlashOpsSt 
+ * \brief low level flash operations, should be implement in flash driver
+ */
+struct uffs_FlashOpsSt {
+	/**
+	 * Initilize flash driver, called once when UFFS initilize partition
+	 *
+	 * \return 0 if no error, return -1 when failed.
+	 *
+	 * \note This function is optional.
+	 */
+	int (*InitFlash)(uffs_Device *dev);
+
+	/**
+	 * Release flash driver, called once when UFFS unmount partition
+	 *
+	 * \return 0 if no error, return -1 when failed.
+	 *
+	 * \note This function is optional.
+	 */
+	int (*ReleaseFlash)(uffs_Device *dev);
+
+	/**
+	 * Read a full nand page, UFFS do the layout.
+	 * 
+	 * \param[out] ecc ecc of page data
+	 *   if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc of data(if ecc != NULL).
+	 *   if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction before return data and flash driver do not need to return ecc.
+	 *   if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_SOFT, flash driver do not need to calculate data ecc and return ecc.
+	 *
+	 * \return	#UFFS_FLASH_NO_ERR: success and/or has no flip bits.
+	 *			#UFFS_FLASH_IO_ERR: I/O error, expect retry ?
+	 *			#UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed (when ecc_opt == UFFS_ECC_HW_AUTO)
+	 *			#UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc (when ecc_opt == UFFS_ECC_HW_AUTO)
+	 *          #UFFS_FLASH_BAD_BLK: if the block is a bad block (e.g., the bad block mark byte is not 0xFF).
+	 *
+	 * \note if data is NULL, do not return data; if spare is NULL, do not return spare; if both data and spare are all NULL,
+	 *       then read bad block mark and return UFFS_FLASH_BAD_BLK if bad block mark is not 0xFF.
+	 *
+	 * \note pad 0xFF for calculating ECC if len < page_data_size
+	 */
+	int (*ReadPage)(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
+						u8 *spare, int spare_len);
+
+	/**
+	 * Read a full nand page, driver do the layout.
+	 *
+	 * \param[out] ecc ecc of page data
+	 *   if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc of data(if ecc != NULL).
+	 *   if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction before return data and flash driver do not need to return ecc.
+	 *   if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_SOFT, flash driver do not need calculate data ecc and return ecc.
+	 *
+	 * \param[out] ecc_store ecc store on spare area
+	 *   if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_HW_AUTO, do not need to return ecc_store.
+	 *
+	 * \note flash driver must provide this function if layout_opt is UFFS_LAYOUT_FLASH.
+	 *       UFFS will use this function (if exist) prio to 'ReadPageSpare()'
+	 *
+	 * \return	#UFFS_FLASH_NO_ERR: success
+	 *			#UFFS_FLASH_IO_ERR: I/O error, expect retry ?
+	 *			#UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed (when ecc_opt == UFFS_ECC_HW_AUTO)
+	 *			#UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc (when ecc_opt == UFFS_ECC_HW_AUTO)
+	 *          #UFFS_FLASH_BAD_BLK: if the block is a bad block (e.g., the bad block mark byte is not 0xFF)
+	 *			#UFFS_FLASH_NOT_SEALED: if the page spare is not sealed properly
+	 *
+	 * \note if data is NULL, do not return data; if ts is NULL, do not read tag; if both data and ts are NULL,
+	 *       then read bad block mark and return UFFS_FLASH_BAD_BLK if bad block mark is not 0xFF.
+	 *
+	 * \note flash driver DO NOT need to do ecc correction for tag,
+	 *		UFFS will take care of tag ecc.
+	 */
+	int (*ReadPageWithLayout)(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
+									uffs_TagStore *ts, u8 *ecc_store);
+
+	/**
+	 * Write a full page, UFFS do the layout for spare area.
+	 *
+	 * \note If you have ecc_opt UFFS_ECC_HW or UFFS_ECC_HW_AUTO, you MUST implement WritePageWithLayout().
+	 *       Implement WritePage() function if you have ecc_opt UFFS_ECC_NONE or UFFS_ECC_SOFT and
+	 *       WritePageWithLayout() is not implemented.
+	 *
+	 * \note If data == NULL && spare == NULL, driver should mark this block as a 'bad block'.
+	 *
+	 * \return	#UFFS_FLASH_NO_ERR: success
+	 *			#UFFS_FLASH_IO_ERR: I/O error, expect retry ?
+	 *			#UFFS_FLASH_BAD_BLK: a bad block detected.
+	 */
+	int (*WritePage)(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *spare, int spare_len);
+
+	/**
+	 * Write full page, flash driver do the layout for spare area.
+	 *
+	 * \note if layout_opt is UFFS_LAYOUT_FLASH or ecc_opt is UFFS_ECC_HW/UFFS_ECC_HW_AUTO, flash driver MUST implement
+	 *       this function. UFFS will use this function (if provided) prio to 'WritePage()'
+	 *
+	 * \param[in] ecc ecc of data. if ecc_opt is UFFS_ECC_SOFT and this function is implemented,
+	 *                UFFS will calculate page data ecc and pass it to WritePageWithLayout().
+	 *            if ecc_opt is UFFS_ECC_NONE/UFFS_ECC_HW/UFFS_ECC_HW_AUTO, UFFS pass ecc = NULL.
+	 *
+	 * \note If data == NULL && ts == NULL, driver should mark this block as a 'bad block'.
+	 *
+	 * \return	#UFFS_FLASH_NO_ERR: success
+	 *			#UFFS_FLASH_IO_ERR: I/O error, expect retry ?
+	 *			#UFFS_FLASH_BAD_BLK: a bad block detected.
+	 */
+	int (*WritePageWithLayout)(uffs_Device *dev, u32 block, u32 page,
+							const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts);
+
+	/**
+	 * Check block status.
+	 *
+	 * \note flash driver may maintain a bad block table to speed up bad block checking or
+	 *		it will require one or two read spare I/O to check block status.
+	 *
+	 * \note if this function is not implented by driver, UFFS check the block_status byte in spare.
+	 *
+	 * \return 1 if it's a bad block, 0 if it's not.
+	 */
+	int (*IsBadBlock)(uffs_Device *dev, u32 block);
+
+	/**
+	 * Mark a new bad block.
+	 *
+	 * \note if this function is not implemented, UFFS mark bad block by call 'WritePage()/WritePageWithLayout()'
+	 *       with: data == NULL && spare == NULL && ts == NULL.
+	 *
+	 * \return 0 if success, otherwise return -1.
+	 */
+	int (*MarkBadBlock)(uffs_Device *dev, u32 block);
+
+	/**
+	 * Erase a block, driver MUST implement this function.
+	 *
+	 * \return	#UFFS_FLASH_NO_ERR: success
+	 *			#UFFS_FLASH_IO_ERR: I/O error, expect retry ?
+	 *			#UFFS_FLASH_BAD_BLK: a bad block detected.
+	 */
+	int (*EraseBlock)(uffs_Device *dev, u32 block);
+};
+
+/** make spare from tag store and ecc */
+void uffs_FlashMakeSpare(uffs_Device *dev, const uffs_TagStore *ts, const u8 *ecc, u8* spare);
+
+/** unload tag and ecc from spare */
+void uffs_FlashUnloadSpare(uffs_Device *dev, const u8 *spare, struct uffs_TagStoreSt *ts, u8 *ecc);
+
+/** read page spare and fill to tag */
+int uffs_FlashReadPageTag(uffs_Device *dev, int block, int page, uffs_Tags *tag);
+
+/** read page data to page buf and do ECC correct */
+int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf, UBOOL skip_ecc);
+
+/** write page data and spare */
+int uffs_FlashWritePageCombine(uffs_Device *dev, int block, int page, uffs_Buf *buf, uffs_Tags *tag);
+
+/** Mark this block as bad block */
+int uffs_FlashMarkBadBlock(uffs_Device *dev, int block);
+
+/** Is this block a bad block ? */
+UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block);
+
+/** Erase flash block */
+int uffs_FlashEraseBlock(uffs_Device *dev, int block);
+
+/* mark a clean page as 'dirty' (and 'invalid') */
+int uffs_FlashMarkDirtyPage(uffs_Device *dev, uffs_BlockInfo *bc, int page);
+
+/* check if the block pages are all clean */
+URET uffs_FlashCheckErasedBlock(uffs_Device *dev, int block);
+	
+/**
+ * get page head info
+ *
+ * \return #UFFS_PAGE_INFO_IOERR if I/O error, otherwise return page info
+ */
+u32 uffs_FlashGetPageInfo(uffs_Device *dev, int block, int page);
+
+/** load uffs_FileInfo from flash storage */
+URET uffs_FlashReadFileinfoPhy(uffs_Device *dev, int block, int page, uffs_FileInfo *info);
+
+/**
+ * Initialize UFFS flash interface
+ */
+URET uffs_FlashInterfaceInit(uffs_Device *dev);
+
+/**
+ * Release UFFS flash interface
+ */
+URET uffs_FlashInterfaceRelease(uffs_Device *dev);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 138 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_fs.h

@@ -0,0 +1,138 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_fs.h
+ * \brief uffs basic file operations
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_FS_H_
+#define _UFFS_FS_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/** file object */
+struct uffs_ObjectSt {
+	/******* objects manager ********/
+	int dev_lock_count;
+	int dev_get_count;
+
+	/******** init level 0 ********/
+	const char * name;					//!< pointer to the start of name, for open or create
+	u32 name_len;						//!< name length
+	u16 sum;							//!< sum of name
+	uffs_Device *dev;					//!< uffs device
+	u32 oflag;
+	u8 type;
+	u16 head_pages;						//!< data pages on file head block
+	u16 parent;
+
+	/******* init level 1 ********/
+	TreeNode *node;						//!< file entry node in tree
+	u16 serial;
+	
+	/******* output ******/
+	int err;							//!< error number
+
+	/******* current *******/
+	u32 pos;							//!< current position in file
+
+	/***** others *******/
+	UBOOL attr_loaded;					//!< attributes loaded ?
+	UBOOL open_succ;					//!< U_TRUE or U_FALSE
+
+};
+
+typedef struct uffs_ObjectSt uffs_Object;
+
+
+
+#define uffs_GetObjectErr(obj) ((obj)->err)
+#define uffs_ClearObjectErr(obj) do { (obj)->err = UENOERR; } while (0)
+
+uffs_Pool * uffs_GetObjectPool(void);
+
+URET uffs_InitObjectBuf(void);
+URET uffs_ReleaseObjectBuf(void);
+int uffs_PutAllObjectBuf(uffs_Device *dev);
+uffs_Object * uffs_GetObject(void);
+void uffs_PutObject(uffs_Object *obj);
+int uffs_GetObjectIndex(uffs_Object *obj);
+uffs_Object * uffs_GetObjectByIndex(int idx);
+
+
+/**
+ * Re-initialize an object.
+ * should call this function if you want to re-use an object.
+ */
+URET uffs_ReInitObject(uffs_Object *obj);
+
+URET uffs_ParseObject(uffs_Object *obj, const char *name);
+
+URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev, 
+								   int dir, const char *name, int name_len, int oflag);
+URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev, 
+								   int dir, const char *name, int name_len, int oflag);
+
+URET uffs_OpenObject(uffs_Object *obj, const char *fullname, int oflag);
+URET uffs_TruncateObject(uffs_Object *obj, u32 remain);
+URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag);
+
+URET uffs_CloseObject(uffs_Object *obj);
+int uffs_WriteObject(uffs_Object *obj, const void *data, int len);
+int uffs_ReadObject(uffs_Object *obj, void *data, int len);
+long uffs_SeekObject(uffs_Object *obj, long offset, int origin);
+int uffs_GetCurOffset(uffs_Object *obj);
+int uffs_EndOfFile(uffs_Object *obj);
+URET uffs_FlushObject(uffs_Object *obj);
+
+URET uffs_RenameObject(const char *old_name, const char *new_name, int *err);
+URET uffs_DeleteObject(const char * name, int *err);
+
+int uffs_GetFreeObjectHandlers(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 83 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_mem.h

@@ -0,0 +1,83 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_MEM_H_
+#define _UFFS_MEM_H_
+
+#include "uffs/uffs_device.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/** uffs memory allocator */
+typedef struct uffs_memAllocatorSt {
+	URET (*init)(struct uffs_DeviceSt *dev);			//!< init memory allocator, setup buffer sizes
+	URET (*release)(struct uffs_DeviceSt *dev);			//!< release memory allocator (for dynamic memory allocation)
+	
+	void * (*malloc)(struct uffs_DeviceSt *dev, unsigned int size); //!< allocate memory (for dynamic memory allocation)
+	URET (*free)(struct uffs_DeviceSt *dev, void *p);   //!< free memory (for dynamic memory allocation)
+
+	void * blockinfo_pool_buf;			//!< block info cache buffers
+	void * pagebuf_pool_buf;			//!< page buffers
+	void * tree_nodes_pool_buf;			//!< tree nodes buffer
+	void * spare_pool_buf;				//!< spare buffers
+
+	int blockinfo_pool_size;			//!< block info cache buffers size
+	int pagebuf_pool_size;				//!< page buffers size
+	int tree_nodes_pool_size;			//!< tree nodes buffer size
+	int spare_pool_size;				//!< spare buffer pool size
+
+	uffs_Pool tree_pool;
+	uffs_Pool spare_pool;
+
+	int spare_data_size;				//!< spare size consumed by UFFS, 
+										//!< calculated by UFFS according to the layout information.
+
+	/* for static memory allocator */
+	char *buf_start;
+	int buf_size;
+	int pos;
+
+
+} uffs_MemAllocator;
+
+void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator);
+void uffs_MemSetupStaticAllocator(uffs_MemAllocator *allocator, void *pool, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 89 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h

@@ -0,0 +1,89 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_mtb.h
+ * \brief mount table related stuff
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_MTB_H_
+#define _UFFS_MTB_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+typedef struct uffs_MountTableEntrySt {
+	uffs_Device *dev;
+	int start_block;
+	int end_block;
+	const char *mount;
+	struct uffs_MountTableEntrySt *next;
+} uffs_MountTable;
+
+/** initialize registered mount table */
+URET uffs_InitMountTable(void);									
+
+/** release registered mount table */
+URET uffs_ReleaseMountTable(void);								
+
+/** get registered mount table */
+uffs_MountTable * uffs_GetMountTable(void);						
+
+/** register mount table */
+int uffs_RegisterMountTable(uffs_MountTable *mtab);				
+
+/** get matched mount point from absolute path */
+int uffs_GetMatchedMountPointSize(const char *path);			
+
+/** get uffs device from mount point */
+uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount);	
+
+/** get uffs device from mount point */
+uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len);	
+
+/** get mount point name from uffs device */
+const char * uffs_GetDeviceMountPoint(uffs_Device *dev);		
+
+/** down crease uffs device references by uffs_GetDeviceXXX() */
+void uffs_PutDevice(uffs_Device *dev);							
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 75 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_os.h

@@ -0,0 +1,75 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_OS_H_
+#define _UFFS_OS_H_
+
+#include <rtthread.h>
+#define RT_THREAD
+#if !defined(RT_THREAD)
+#include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define UFFS_TASK_ID_NOT_EXIST	-1
+
+typedef void * OSSEM;
+#define OSSEM_NOT_INITED	(NULL)
+
+#if !defined(RT_THREAD)
+struct uffs_DebugMsgOutputSt {
+	void (*output)(const char *msg);
+	void (*vprintf)(const char *fmt, va_list args);
+};
+
+void uffs_SetupDebugOutput(void);
+#endif
+
+/* OS specific functions */
+int uffs_SemCreate(OSSEM *sem);
+int uffs_SemWait(OSSEM sem);
+int uffs_SemSignal(OSSEM sem);
+int uffs_SemDelete(OSSEM *sem);
+
+int uffs_OSGetTaskId(void);	//get current task id
+unsigned int uffs_GetCurDateTime(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 94 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_pool.h

@@ -0,0 +1,94 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_pool.h
+ * \brief Fast fixed size memory pool management.
+ * \author Ricky Zheng, Simon Kallweit
+ */
+
+#ifndef _UFFS_POOL_H_
+#define _UFFS_POOL_H_
+
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_os.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/**
+ * \struct uffs_PoolEntrySt
+ * \brief Helper type for free buffer entries.
+ */
+typedef struct uffs_PoolEntrySt {
+    struct uffs_PoolEntrySt *next;
+} uffs_PoolEntry;
+
+/**
+ * \struct uffs_PoolSt
+ * \brief Memory pool.
+ */
+typedef struct uffs_PoolSt {
+	u8 *mem;					//!< memory pool
+	u32 buf_size;				//!< size of a buffer
+	u32 num_bufs;				//!< number of buffers in the pool
+	uffs_PoolEntry *free_list;	//!< linked list of free buffers
+	OSSEM sem;					//!< buffer lock
+} uffs_Pool;
+
+URET uffs_PoolInit(uffs_Pool *pool, void *mem, u32 mem_size, u32 buf_size, u32 num_bufs);
+URET uffs_PoolRelease(uffs_Pool *pool);
+
+UBOOL uffs_PoolVerify(uffs_Pool *pool, void *p);
+
+void *uffs_PoolGet(uffs_Pool *pool);
+void *uffs_PoolGetLocked(uffs_Pool *pool);
+
+int uffs_PoolPut(uffs_Pool *pool, void *p);
+int uffs_PoolPutLocked(uffs_Pool *pool, void *p);
+
+void *uffs_PoolGetBufByIndex(uffs_Pool *pool, u32 index);
+u32 uffs_PoolGetIndex(uffs_Pool *pool, void *p);
+UBOOL uffs_PoolCheckFreeList(uffs_Pool *pool, void *p);
+
+void * uffs_PoolFindNextAllocated(uffs_Pool *pool, void *from);
+
+int uffs_PoolGetFreeCount(uffs_Pool *pool);
+int uffs_PoolPutAll(uffs_Pool *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _UFFS_POOL_H_

+ 337 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h

@@ -0,0 +1,337 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_public.h
+ * \brief public data structures for uffs
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_PUBLIC_H_
+#define _UFFS_PUBLIC_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs.h"
+#include "uffs/uffs_pool.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0]))
+#endif
+
+#ifndef offsetof
+# define offsetof(T, x) ((size_t) &((T *)0)->x)
+#endif
+#ifndef container_of
+#define container_of(p, T, x) ((T *)((char *)(p) - offsetof(T,x)))
+#endif
+
+/** 
+ * \def MAX_FILENAME_LENGTH 
+ * \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name)
+ *    !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!!
+ */
+#define MAX_FILENAME_LENGTH         128
+
+/** \note 8-bits attr goes to uffs_dirent::d_type */
+#define FILE_ATTR_DIR       (1 << 7)    //!< attribute for directory
+#define FILE_ATTR_WRITE     (1 << 0)    //!< writable
+
+
+/**
+ * \structure uffs_FileInfoSt
+ * \brief file/dir entry info in physical storage format
+ */
+struct uffs_FileInfoSt {
+    u32 attr;               //!< file/dir attribute
+    u32 create_time;
+    u32 last_modify;
+    u32 access;
+    u32 reserved;
+    u32 name_len;           //!< length of file/dir name
+    char name[MAX_FILENAME_LENGTH];
+}; //6*4 + sizeof(name) = 24 + 128 = 152 Bytes
+typedef struct uffs_FileInfoSt uffs_FileInfo;
+
+/**
+ * \struct uffs_ObjectInfoSt
+ * \brief object info
+ */
+typedef struct uffs_ObjectInfoSt {
+    uffs_FileInfo info;
+    u32 len;                //!< length of file
+    u16 serial;             //!< object serial num
+} uffs_ObjectInfo;
+
+
+/**
+ * \struct uffs_TagStoreSt
+ * \brief uffs tag, 8 bytes, will be store in page spare area.
+ */
+struct uffs_TagStoreSt {
+	u32 dirty:1;		//!< 0: dirty, 1: clear
+	u32 valid:1;		//!< 0: valid, 1: invalid
+	u32 type:2;			//!< block type: #UFFS_TYPE_DIR, #UFFS_TYPE_FILE, #UFFS_TYPE_DATA
+	u32 block_ts:2;		//!< time stamp of block;
+	u32 data_len:12;	//!< length of page data
+	u32 serial:14;		//!< serial number
+
+	u32 parent:10;		//!< parent's serial number
+	u32 page_id:6;		//!< page id
+	u32 reserved:4;		//!< reserved, for UFFS2
+	u32 tag_ecc:12;		//!< tag ECC
+};
+
+#define TAG_ECC_DEFAULT (0xFFF)	//!< 12-bit '1'
+
+
+/** 
+ * \struct uffs_TagsSt
+ */
+struct uffs_TagsSt {
+	struct uffs_TagStoreSt s;		/* store must be the first member */
+
+	/** data_sum for file or dir name */
+	u16 data_sum;
+
+	/** internal used */
+	u8 seal_byte;			//!< seal byte.
+};
+
+/** 
+ * \struct uffs_MiniHeaderSt
+ * \brief the mini header resides on the head of page data
+ */
+struct uffs_MiniHeaderSt {
+	u8 status;
+	u8 reserved;
+	u16 crc;
+};
+
+
+/** uffs_TagsSt.dirty */
+#define TAG_VALID		0
+#define TAG_INVALID		1
+
+/** uffs_TagsSt.valid */
+#define TAG_DIRTY		0
+#define TAG_CLEAR		1
+
+#define TAG_IS_DIRTY(tag) (*((u32 *) &((tag)->s)) != 0xFFFFFFFF)	// tag is dirty if first 4 bytes not all 0xFF
+#define TAG_IS_VALID(tag) ((tag)->s.valid == TAG_VALID)
+#define TAG_IS_SEALED(tag) ((tag)->seal_byte != 0xFF)
+
+#define TAG_IS_GOOD(tag) (TAG_IS_SEALED(tag) && TAG_IS_VALID(tag))
+
+#define TAG_VALID_BIT(tag) (tag)->s.valid
+#define TAG_DIRTY_BIT(tag) (tag)->s.dirty
+#define TAG_SERIAL(tag) (tag)->s.serial
+#define TAG_PARENT(tag) (tag)->s.parent
+#define TAG_PAGE_ID(tag) (tag)->s.page_id
+#define TAG_DATA_LEN(tag) (tag)->s.data_len
+#define TAG_TYPE(tag) (tag)->s.type
+#define TAG_BLOCK_TS(tag) (tag)->s.block_ts
+#define SEAL_TAG(tag) (tag)->seal_byte = 0
+
+int uffs_GetFirstBlockTimeStamp(void);
+int uffs_GetNextBlockTimeStamp(int prev);
+UBOOL uffs_IsSrcNewerThanObj(int src, int obj);
+
+
+#include "uffs_device.h"
+
+
+
+/********************************** debug & error *************************************/
+#define UFFS_MSG_NOISY		-1
+#define UFFS_MSG_NORMAL		0
+#define UFFS_MSG_SERIOUS	1
+#define UFFS_MSG_DEAD		2
+#define UFFS_MSG_NOMSG		100
+
+#define TENDSTR "\n"
+
+#if !defined(RT_THREAD)
+struct uffs_DebugMsgOutputSt;
+URET uffs_InitDebugMessageOutput(struct uffs_DebugMsgOutputSt *ops, int msg_level);
+void uffs_DebugSetMessageLevel(int msg_level);
+
+void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const char *errFmt, ...);
+void uffs_AssertCall(const char *file, int line, const char *msg, ...);
+#else
+
+#define UFFS_DBG_LEVEL  UFFS_MSG_NORMAL
+
+#ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG
+#define uffs_DebugMessage(level, prefix, suffix, errFmt, ...) do { \
+	if (level >= UFFS_DBG_LEVEL) \
+		rt_kprintf(prefix errFmt suffix, ##__VA_ARGS__); \
+} while(0)
+
+#define uffs_AssertCall(file, line, msg, ...) \
+	rt_kprintf("ASSERT %s:%d - :" msg "\n", (const char *)file, (int)line, ##__VA_ARGS__)
+#else
+#define uffs_DebugMessage(level, prefix, suffix, errFmt, ...)
+#define uffs_AssertCall(file, line, msg, ...)
+#endif //CONFIG_ENABLE_UFFS_DEBUG_MSG
+#endif //RT_THREAD
+
+#ifdef _COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_
+/* For those compilers do not support valist parameter replace in macro define */
+void uffs_Perror(int level, const char *fmt, ...);
+void uffs_PerrorRaw(int level, const char *fmt, ...);
+UBOOL uffs_Assert(UBOOL expr, const char *fmt, ...);
+#else
+
+#if !defined(RT_THREAD)
+#define uffs_Perror(level, fmt, ... ) \
+	uffs_DebugMessage(level, PFX, TENDSTR, fmt, ## __VA_ARGS__)
+
+#define uffs_PerrorRaw(level, fmt, ... ) \
+	uffs_DebugMessage(level, NULL, NULL, fmt, ## __VA_ARGS__)
+
+#else
+
+#ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG
+
+#define uffs_Perror(level, fmt, ... ) do{\
+	if (level >= UFFS_DBG_LEVEL) \
+		rt_kprintf(PFX fmt TENDSTR, ##__VA_ARGS__); \
+} while(0)
+
+#define uffs_PerrorRaw(level, fmt, ... ) do{\
+	if (level >= UFFS_DBG_LEVEL) \
+		rt_kprintf(fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define uffs_Perror(level, fmt, ... )
+#define uffs_PerrorRaw(level, fmt, ... )
+#endif // CONFIG_ENABLE_UFFS_DEBUG_MSG
+#endif // RT_THREAD
+
+#define uffs_Assert(expr, msg, ...) \
+	((expr) ? U_TRUE : (uffs_AssertCall(__FILE__, __LINE__, msg, ## __VA_ARGS__), U_FALSE))
+
+#endif //_COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_
+
+#define uffs_Panic() \
+	do { \
+		uffs_AssertCall(__FILE__, __LINE__, "Bam !!\n"); \
+		while(1); \
+	} while(0)
+
+/********************************** NAND **********************************************/
+//NAND flash specific file must implement these interface
+URET uffs_LoadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag);
+URET uffs_WritePageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag);
+URET uffs_MakePageValid(uffs_Device *dev, int block, int page, uffs_Tags *tag);
+UBOOL uffs_IsBlockBad(uffs_Device *dev, uffs_BlockInfo *bc);
+
+/********************************** Public defines *****************************/
+/**
+ * \def UFFS_ALL_PAGES 
+ * \brief UFFS_ALL_PAGES if this value presented, that means the objects are all pages in the block
+ */
+#define UFFS_ALL_PAGES (0xffff)
+
+/** 
+ * \def UFFS_INVALID_PAGE
+ * \brief macro for invalid page number
+ */
+#define UFFS_INVALID_PAGE	(0xfffe)
+
+/** 
+ * \def UFFS_INVALID_BLOCK
+ * \brief macro for invalid block number
+ */
+#define UFFS_INVALID_BLOCK	(0xfffe)
+
+
+URET uffs_NewBlock(uffs_Device *dev, u16 block, uffs_Tags *tag, uffs_Buf *buf);
+URET uffs_BlockRecover(uffs_Device *dev, uffs_BlockInfo *old, u16 newBlock);
+URET uffs_PageRecover(uffs_Device *dev, 
+					  uffs_BlockInfo *bc, 
+					  u16 oldPage, 
+					  u16 newPage, 
+					  uffs_Buf *buf);
+int uffs_FindFreePageInBlock(uffs_Device *dev, uffs_BlockInfo *bc);
+u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page);
+u16 uffs_FindFirstFreePage(uffs_Device *dev, uffs_BlockInfo *bc, u16 pageFrom);
+u16 uffs_FindPageInBlockWithPageId(uffs_Device *dev, uffs_BlockInfo *bc, u16 page_id);
+
+u8 uffs_MakeSum8(const void *p, int len);
+u16 uffs_MakeSum16(const void *p, int len);
+URET uffs_CreateNewFile(uffs_Device *dev, u16 parent, u16 serial, uffs_BlockInfo *bc, uffs_FileInfo *fi);
+
+int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type);
+UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page);
+int uffs_GetFreePagesCount(uffs_Device *dev, uffs_BlockInfo *bc);
+UBOOL uffs_IsDataBlockReguFull(uffs_Device *dev, uffs_BlockInfo *bc);
+UBOOL uffs_IsThisBlockUsed(uffs_Device *dev, uffs_BlockInfo *bc);
+
+int uffs_GetBlockTimeStamp(uffs_Device *dev, uffs_BlockInfo *bc);
+
+int uffs_GetDeviceUsed(uffs_Device *dev);
+int uffs_GetDeviceFree(uffs_Device *dev);
+int uffs_GetDeviceTotal(uffs_Device *dev);
+
+URET uffs_LoadMiniHeader(uffs_Device *dev, int block, u16 page, struct uffs_MiniHeaderSt *header);
+
+
+/* some functions from uffs_fd.c */
+void uffs_FdSignatureIncrease(void);
+URET uffs_DirEntryBufInit(void);
+URET uffs_DirEntryBufRelease(void);
+uffs_Pool * uffs_DirEntryBufGetPool(void);
+int uffs_DirEntryBufPutAll(uffs_Device *dev);
+
+
+/************************************************************************/
+/*  init functions                                                                     */
+/************************************************************************/
+URET uffs_InitDevice(uffs_Device *dev);
+URET uffs_ReleaseDevice(uffs_Device *dev);
+
+
+URET uffs_InitFlashClass(uffs_Device *dev);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif	// _UFFS_PUBLIC_H_
+

+ 237 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h

@@ -0,0 +1,237 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_TREE_H_
+#define _UFFS_TREE_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_pool.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#define UFFS_TYPE_DIR		0
+#define UFFS_TYPE_FILE		1
+#define UFFS_TYPE_DATA		2
+#define UFFS_TYPE_RESV		3
+#define UFFS_TYPE_INVALID	0xFF
+
+struct uffs_NodeTypeNameMapSt {
+	int type;
+	const char *name;
+};
+
+#define UFFS_TYPE_NAME_MAP { \
+	{UFFS_TYPE_DIR, "DIR"}, \
+	{UFFS_TYPE_FILE, "FILE"}, \
+	{UFFS_TYPE_DATA, "DATA"}, \
+	{UFFS_TYPE_RESV, "RESV"}, \
+	{UFFS_TYPE_INVALID, "INVALID"} \
+}
+
+struct BlockListSt {	/* 12 bytes */
+	struct uffs_TreeNodeSt * next;
+	struct uffs_TreeNodeSt * prev;
+	u16 block;
+	union {
+		u16 serial;    /* for suspended block list */
+		u8 need_check; /* for erased block list */
+	}u;
+};
+
+struct DirhSt {		/* 8 bytes */
+	u16 checksum;	/* check sum of dir name */
+	u16 block;
+	u16 parent;
+	u16 serial;
+};
+
+
+struct FilehSt {	/* 12 bytes */
+	u16 block;
+	u16 checksum;	/* check sum of file name */
+	u16 parent;
+	u16 serial;
+	u32 len;		/* file length total */
+};
+
+struct FdataSt {	/* 10 bytes */
+	u16 block;
+	u16 parent;
+	u32 len;		/* file data length on this block */
+	u16 serial;
+};
+
+//UFFS TreeNode (14 or 16 bytes)
+typedef struct uffs_TreeNodeSt {
+	union {
+		struct BlockListSt list;
+		struct DirhSt dir;
+		struct FilehSt file;
+		struct FdataSt data;
+	} u;
+	u16 hash_next;		
+	u16 hash_prev;			
+} TreeNode;
+
+
+//TODO: UFFS2 Tree structures
+/*
+struct FdataSt {
+	u32 len;
+};
+
+struct filebSt {
+	u16 bls;		//how many blocks this file contents ...
+	u8 offs;		//the offset of this file header on FILE block
+	u8 sum;			//short sum of file name
+};
+
+//Extra data structure for storing file length information
+struct FilehSt {
+	u32 len;
+};
+
+//UFFS2 TreeNode (12 bytes)
+typedef struct uffs_TreeNodeSt {
+	u16 nextIdx;
+	u16 block;
+	u16 parent;
+	u16 serial;
+	union {
+		struct FilehSt h;
+		struct filedSt file;
+		struct data;
+	} u;
+} TreeNode;
+
+*/
+
+
+#define EMPTY_NODE 0xffff				//!< special index num of empty node.
+
+#define ROOT_DIR_SERIAL	0				//!< serial num of root dir
+#define MAX_UFFS_FSN			0x3ff	//!< maximum dir|file serial number (uffs_TagStore#parent: 10 bits)
+#define MAX_UFFS_FDN			0x3fff	//!< maximum file data block serial numbers (uffs_TagStore#serial: 14 bits)
+#define PARENT_OF_ROOT			0xfffd	//!< parent of ROOT ? kidding me ...
+#define INVALID_UFFS_SERIAL		0xffff	//!< invalid serial num
+
+#define DIR_NODE_HASH_MASK		0x1f
+#define DIR_NODE_ENTRY_LEN		(DIR_NODE_HASH_MASK + 1)
+
+#define FILE_NODE_HASH_MASK		0x3f
+#define FILE_NODE_ENTRY_LEN		(FILE_NODE_HASH_MASK + 1)
+
+#define DATA_NODE_HASH_MASK		0x1ff
+#define DATA_NODE_ENTRY_LEN		(DATA_NODE_HASH_MASK + 1)
+#define FROM_IDX(idx, pool)		((TreeNode *)uffs_PoolGetBufByIndex(pool, idx))
+#define TO_IDX(p, pool)			((u16)uffs_PoolGetIndex(pool, (void *) p))
+
+
+#define GET_FILE_HASH(serial)			(serial & FILE_NODE_HASH_MASK)
+#define GET_DIR_HASH(serial)			(serial & DIR_NODE_HASH_MASK)
+#define GET_DATA_HASH(parent, serial)	((parent + serial) & DATA_NODE_HASH_MASK)
+
+
+struct uffs_TreeSt {
+	TreeNode *erased;					//!< erased block list head
+	TreeNode *erased_tail;				//!< erased block list tail
+	TreeNode *suspend;					//!< suspended block list
+	int erased_count;					//!< erased block counter
+	TreeNode *bad;						//!< bad block list
+	int bad_count;						//!< bad block count
+	u16 dir_entry[DIR_NODE_ENTRY_LEN];
+	u16 file_entry[FILE_NODE_ENTRY_LEN];
+	u16 data_entry[DATA_NODE_ENTRY_LEN];
+	u16 max_serial;
+};
+
+
+URET uffs_TreeInit(uffs_Device *dev);
+URET uffs_TreeRelease(uffs_Device *dev);
+URET uffs_BuildTree(uffs_Device *dev);
+u16 uffs_FindFreeFsnSerial(uffs_Device *dev);
+TreeNode * uffs_TreeFindFileNode(uffs_Device *dev, u16 serial);
+TreeNode * uffs_TreeFindFileNodeWithParent(uffs_Device *dev, u16 parent);
+TreeNode * uffs_TreeFindDirNode(uffs_Device *dev, u16 serial);
+TreeNode * uffs_TreeFindDirNodeWithParent(uffs_Device *dev, u16 parent);
+TreeNode * uffs_TreeFindFileNodeByName(uffs_Device *dev, const char *name, u32 len, u16 sum, u16 parent);
+TreeNode * uffs_TreeFindDirNodeByName(uffs_Device *dev, const char *name, u32 len, u16 sum, u16 parent);
+TreeNode * uffs_TreeFindDataNode(uffs_Device *dev, u16 parent, u16 serial);
+
+
+TreeNode * uffs_TreeFindDirNodeByBlock(uffs_Device *dev, u16 block);
+TreeNode * uffs_TreeFindFileNodeByBlock(uffs_Device *dev, u16 block);
+TreeNode * uffs_TreeFindDataNodeByBlock(uffs_Device *dev, u16 block);
+TreeNode * uffs_TreeFindErasedNodeByBlock(uffs_Device *dev, u16 block);
+TreeNode * uffs_TreeFindBadNodeByBlock(uffs_Device *dev, u16 block);
+
+void uffs_TreeSuspendAdd(uffs_Device *dev, TreeNode *node);
+TreeNode * uffs_TreeFindSuspendNode(uffs_Device *dev, u16 serial);
+void uffs_TreeRemoveSuspendNode(uffs_Device *dev, TreeNode *node);
+
+#define SEARCH_REGION_DIR		1
+#define SEARCH_REGION_FILE		2
+#define SEARCH_REGION_DATA		4
+#define SEARCH_REGION_BAD		8
+#define SEARCH_REGION_ERASED	16
+TreeNode * uffs_TreeFindNodeByBlock(uffs_Device *dev, u16 block, int *region);
+
+
+
+UBOOL uffs_TreeCompareFileName(uffs_Device *dev, const char *name, u32 len, u16 sum, TreeNode *node, int type);
+
+TreeNode * uffs_TreeGetErasedNode(uffs_Device *dev);
+
+void uffs_InsertNodeToTree(uffs_Device *dev, u8 type, TreeNode *node);
+void uffs_InsertToErasedListHead(uffs_Device *dev, TreeNode *node);
+void uffs_TreeInsertToErasedListTail(uffs_Device *dev, TreeNode *node);
+void uffs_TreeInsertToErasedListTailEx(uffs_Device *dev, TreeNode *node, int need_check);
+void uffs_TreeInsertToBadBlockList(uffs_Device *dev, TreeNode *node);
+
+void uffs_BreakFromEntry(uffs_Device *dev, u8 type, TreeNode *node);
+
+void uffs_TreeSetNodeBlock(u8 type, TreeNode *node, u16 block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
+
+

+ 160 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_types.h

@@ -0,0 +1,160 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_TYPES_H_
+#define _UFFS_TYPES_H_
+
+#ifdef __CDT_PARSER__
+#undef __cplusplus
+#endif
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifdef _UBASE_
+#include <sys/utypes.h>
+#endif
+
+/** 
+ * \file uffs_types.h
+ * \brief basic types used on uffs
+ * \author Ricky Zheng
+ */
+
+/* basic types */
+
+/** \typedef i8 
+ * \brief 8 bit integer
+ */
+typedef char i8;
+
+/** \typedef u8 
+ * \brief 8 bit unsigned integer
+ */
+typedef unsigned char u8;
+
+/** \typedef i16 
+ * \brief 16 bit integer
+ */
+typedef short int i16;
+
+
+/** \typedef u16
+ * \brief 16 bit unsigned integer
+ */
+typedef unsigned short int u16;
+
+
+/** \typedef i32
+ * \brief 32 bit integer
+ */
+typedef int i32;
+
+/** \typedef u32 
+ * \brief 32 bit unsigned integer
+ */
+typedef unsigned int u32;
+
+
+#ifndef _UBASE_
+
+#ifndef TRUE
+#define TRUE	1
+#endif
+
+#ifndef FALSE
+#define FALSE	0
+#endif
+
+/* boolean type */
+
+/** \typedef UBOOL 
+ * \brief boolean type for uffs, the value would be: #U_TRUE or #U_FALSE
+ */
+typedef int UBOOL;
+
+/** \def U_TRUE 
+ * \brief boolean true for uffs
+ */
+#define U_TRUE (TRUE)
+
+
+/** \def U_FALSE 
+ * \brief boolean false for uffs
+ */
+#define U_FALSE (FALSE)
+
+
+/** \typedef URET 
+ * \brief return type for uffs, should be #U_FAIL or #U_SUCC
+ */
+typedef int URET;
+
+/** \def U_FAIL 
+ * \brief indicator of fail
+ */
+#define U_FAIL -1
+
+/** \def U_SUCC 
+ * \brief indicator of successful
+ */
+#define U_SUCC 0
+
+/** \def IS_SUCC(ret) 
+ * \brief is it successful ?
+ */
+#define IS_SUCC(ret) (ret >= 0 ? U_TRUE : U_FALSE)
+
+
+/** \def IS_FAIL(ret) 
+ * \brief is it fail ?
+ */
+#define IS_FAIL(ret) (ret < 0 ? U_TRUE : U_FALSE)
+
+#ifndef NULL
+/** \def NULL 
+ * \brief zero for pointer
+ */
+#define NULL 0
+#endif
+
+#endif // _UBASE_
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 64 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_utils.h

@@ -0,0 +1,64 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_UTILS_H_
+#define _UFFS_UTILS_H_
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_device.h"
+#include "uffs/uffs_core.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+//get UFFS disk version, if fail, return 0
+int uffs_GetUFFSVersion(struct uffs_DeviceSt *dev);
+
+void uffs_InitGlobalFsLock(void);
+void uffs_ReleaseGlobalFsLock(void);
+void uffs_GlobalFsLockLock(void);
+void uffs_GlobalFsLockUnlock(void);
+
+URET uffs_FormatDevice(uffs_Device *dev, UBOOL force);
+
+#ifdef __cplusplus
+}
+#endif
+
+typedef void dump_msg_cb(struct uffs_DeviceSt *dev, const char *fmt, ...);
+
+void uffs_DumpDevice(struct uffs_DeviceSt *dev, dump_msg_cb *dump);
+
+#endif
+

+ 55 - 0
components/dfs/filesystems/uffs/src/inc/uffs/uffs_version.h

@@ -0,0 +1,55 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef _UFFS_VERSION_H_
+#define _UFFS_VERSION_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#define UFFS_VERSION		0x01030400	//"01.03.0400"
+
+const char * uffs_Version2Str(int ver);
+int uffs_GetVersion(void);
+int uffs_GetMainVersion(int ver);
+int uffs_GetMinorVersion(int ver);
+int uffs_GetTrivialVersion(int ver);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 13 - 0
components/dfs/filesystems/uffs/src/platform/CMakeLists.txt

@@ -0,0 +1,13 @@
+IF (UNIX)
+	SET (libplatform_SRCS posix/uffs_os.c posix/uffs_config.h)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix)
+ENDIF()
+
+IF (WIN32)
+	SET (libplatform_SRCS win32/uffs_os.c win32/uffs_config.h)
+	INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32)
+ENDIF()
+
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
+ADD_LIBRARY(platform STATIC ${libplatform_SRCS} )
+

+ 322 - 0
components/dfs/filesystems/uffs/src/platform/posix/uffs_config.h

@@ -0,0 +1,322 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_config.h
+ * \brief basic configuration of uffs
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_CONFIG_H_
+#define _UFFS_CONFIG_H_
+
+/**
+ * \def UFFS_MAX_PAGE_SIZE
+ * \note maximum page size UFFS support
+ */
+#define UFFS_MAX_PAGE_SIZE		2048
+
+/**
+ * \def UFFS_MAX_SPARE_SIZE
+ */
+#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8)
+
+/**
+ * \def UFFS_MAX_ECC_SIZE
+ */
+#define UFFS_MAX_ECC_SIZE  ((UFFS_MAX_PAGE_SIZE / 256) * 5)
+
+/**
+ * \def MAX_CACHED_BLOCK_INFO
+ * \note uffs cache the block info for opened directories and files,
+ *       a practical value is 5 ~ MAX_OBJECT_HANDLE
+ */
+#define MAX_CACHED_BLOCK_INFO	50
+
+/** 
+ * \def MAX_PAGE_BUFFERS
+ * \note the bigger value will bring better read/write performance.
+ *       but few writing performance will be improved when this 
+ *       value is become larger than 'max pages per block'
+ */
+#define MAX_PAGE_BUFFERS		40
+
+
+/** 
+ * \def CLONE_BUFFER_THRESHOLD
+ * \note reserve buffers for clone. 1 or 2 should be enough.
+ */
+#define CLONE_BUFFERS_THRESHOLD	2
+
+/**
+ * \def MAX_SPARE_BUFFERS
+ * \note spare buffers are used for lower level flash operations,
+ *		 5 should be enough.
+ */
+#define MAX_SPARE_BUFFERS		5
+
+
+/**
+ * \def MAX_DIRTY_PAGES_IN_A_BLOCK 
+ * \note this value should be between '2' and the lesser of
+ *		 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1).
+ *
+ *       the smaller the value the frequently the buffer will be flushed.
+ */
+#define MAX_DIRTY_PAGES_IN_A_BLOCK 32	
+
+/**
+ * \def MAX_DIRTY_BUF_GROUPS
+ */
+#define MAX_DIRTY_BUF_GROUPS	3
+
+/**
+ * \def CONFIG_ENABLE_UFFS_DEBUG_MSG
+ * \note Enable debug message output. You must call uffs_InitDebugMessageOutput()
+ *      to initialize debug apart from enable debug feature.
+ */
+#define CONFIG_ENABLE_UFFS_DEBUG_MSG
+
+/**
+ * \def CONFIG_USE_GLOBAL_FS_LOCK
+ * \note use global lock instead of per-device lock.
+ *       this is required if you use fd APIs in multi-thread environment.
+ */
+#define CONFIG_USE_GLOBAL_FS_LOCK
+
+
+/**
+ * \def CONFIG_USE_PER_DEVICE_LOCK
+ * \note use per-device lock.
+ *		 this is required if you use fs APIs in multi-thread environment.
+ */
+//#define CONFIG_USE_PER_DEVICE_LOCK
+
+
+
+/**
+ * \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR
+ * \note uffs will use static memory allocator if this is defined.
+ *       to use static memory allocator, you need to provide memory
+ *       buffer when creating uffs_Device.
+ *
+ *       use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size.
+ */
+#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0
+
+/**
+ * \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR
+ * \note  using system platform's 'malloc' and 'free'.
+ */
+#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1
+
+
+
+/** 
+ * \def CONFIG_FLUSH_BUF_AFTER_WRITE
+ * \note UFFS will write all data directly into flash in 
+ *       each 'write' call if you enable this option.
+ *       (which means lesser data lost when power failure but
+ *		 poorer writing performance).
+ *		 It's not recommended to open this define for normal applications.
+ */
+#define CONFIG_FLUSH_BUF_AFTER_WRITE
+
+
+/**
+ * \def CONFIG_UFFS_AUTO_LAYOUT_MTD_COMP
+ * \note Use Linux MTD compatiable spare placement for UFFS_LAYOUT_AUTO,
+ *       only valid for page data size 512 or 2048.
+ */
+//#define CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME
+
+
+/** 
+ * \def MAX_OBJECT_HANDLE
+ * maximum number of object handle 
+ */
+#define MAX_OBJECT_HANDLE	50
+#define FD_SIGNATURE_SHIFT	6	
+
+
+/**
+ * \def MAX_DIR_HANDLE
+ * maximum number of uffs_DIR
+ */
+#define MAX_DIR_HANDLE 10	
+
+/**
+ * \def MINIMUN_ERASED_BLOCK
+ *  UFFS will not allow appending or creating new files when the free/erased block
+ *  is lower then MINIMUN_ERASED_BLOCK.
+ */
+#define MINIMUN_ERASED_BLOCK 2
+
+/**
+ * \def CONFIG_CHANGE_MODIFY_TIME
+ * \note If defined, closing a file which is opened for writing/appending will
+ *       update the file's modify time as well. Disable this feature will save a
+ *       lot of writing activities if you frequently open files for write and close it.
+ */
+//#define CONFIG_CHANGE_MODIFY_TIME
+
+
+/**
+ * \def CONFIG_ENABLE_BAD_BLOCK_VERIFY
+ * \note allow erase and verify block marked as 'bad' when format UFFS partition.
+ *		it's not recommended for most NAND flash.
+ */
+#define CONFIG_ENABLE_BAD_BLOCK_VERIFY
+
+/**
+ * \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
+ * \note erase block again before mark bad block
+ */
+//#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
+
+/**
+ * \def CONFIG_PAGE_WRITE_VERIFY
+ * \note verify page data after write, for extra safe data storage.
+ */
+#define CONFIG_PAGE_WRITE_VERIFY
+
+/**
+ * \def CONFIG_BAD_BLOCK_POLICY_STRICT
+ * \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found;
+ *       otherwise, UFFS report bad block only when ECC failed or reported
+ *		 by low level flash driver.
+ *
+ * \note Enable this will ensure your data always be stored on completely good blocks.
+ */
+#define CONFIG_BAD_BLOCK_POLICY_STRICT
+
+
+/**
+ * \def CONFIG_ENABLE_PAGE_DATA_CRC
+ * \note If this is enabled, UFFS save page data CRC16 sum in mini header,
+ *       it provides extra protection for data integrity.
+ */
+#define CONFIG_ENABLE_PAGE_DATA_CRC
+
+
+/** micros for calculating buffer sizes */
+
+/**
+ *	\def UFFS_BLOCK_INFO_BUFFER_SIZE
+ *	\brief calculate memory bytes for block info caches
+ */
+#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block)	\
+			(											\
+				(										\
+					sizeof(uffs_BlockInfo) +			\
+					sizeof(uffs_PageSpare) * n_pages_per_block \
+				 ) * MAX_CACHED_BLOCK_INFO				\
+			)
+
+/**
+ *	\def UFFS_PAGE_BUFFER_SIZE
+ *	\brief calculate memory bytes for page buffers
+ */
+#define UFFS_PAGE_BUFFER_SIZE(n_page_size)	\
+			(								\
+				(							\
+					sizeof(uffs_Buf) + n_page_size	\
+				) * MAX_PAGE_BUFFERS		\
+			)
+
+/**
+ *	\def UFFS_TREE_BUFFER_SIZE
+ *	\brief calculate memory bytes for tree nodes
+ */
+#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks)
+
+
+#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE)
+
+
+/**
+ *	\def UFFS_STATIC_BUFF_SIZE
+ *	\brief calculate total memory usage of uffs system
+ */
+#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \
+			(		\
+				UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \
+				UFFS_PAGE_BUFFER_SIZE(n_page_size) + \
+				UFFS_TREE_BUFFER_SIZE(n_blocks) + \
+				UFFS_SPARE_BUFFER_SIZE \
+			 )
+
+
+
+/* config check */
+#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3
+#error "MAX_PAGE_BUFFERS is too small"
+#endif
+
+#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2)
+#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2"
+#endif
+
+#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK)
+#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)"
+#endif
+
+#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2)
+#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled."
+#endif
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1
+#error "Please enable ONLY one memory allocator"
+#endif
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0
+#error "Please enable ONE of memory allocators"
+#endif
+
+#if defined(CONFIG_USE_GLOBAL_FS_LOCK) && defined(CONFIG_USE_PER_DEVICE_LOCK)
+#error "enable either CONFIG_USE_GLOBAL_FS_LOCK or CONFIG_USE_PER_DEVICE_LOCK, not both"
+#endif
+
+#if (MAX_OBJECT_HANDLE > (1 << FD_SIGNATURE_SHIFT))
+#error "Please increase FD_SIGNATURE_SHIFT !"
+#endif
+
+#ifdef WIN32
+# pragma warning(disable : 4996)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4214)
+# pragma warning(disable : 4127)
+# pragma warning(disable : 4389)
+# pragma warning(disable : 4100)
+#endif
+
+#endif

+ 148 - 0
components/dfs/filesystems/uffs/src/platform/posix/uffs_os.c

@@ -0,0 +1,148 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_os_posix.c
+ * \brief Emulation on POSIX host. This is just a dumb implementation, does not really create semaphores.
+ * \author Ricky Zheng
+ */
+
+#include "uffs_config.h"
+#include "uffs/uffs_os.h"
+#include "uffs/uffs_public.h"
+#include <memory.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#define PFX "os  : "
+
+int uffs_SemCreate(OSSEM *sem)
+{
+	pthread_mutex_t *mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+	int ret = -1;
+
+	if (mutex) {
+		ret = pthread_mutex_init(mutex, NULL /* default attr */);
+		if (ret == 0) {
+			*sem = (OSSEM *)mutex;			
+		}
+		else {
+			free(mutex);
+		}
+	}
+	
+	return ret;
+}
+
+int uffs_SemWait(OSSEM sem)
+{
+	return pthread_mutex_lock((pthread_mutex_t *)sem);
+}
+
+int uffs_SemSignal(OSSEM sem)
+{
+	return pthread_mutex_unlock((pthread_mutex_t *)sem);;
+}
+
+int uffs_SemDelete(OSSEM *sem)
+{
+	pthread_mutex_t *mutex = (pthread_mutex_t *) (*sem);
+	int ret = -1;
+	
+	if (mutex) {
+		ret = pthread_mutex_destroy(mutex);
+		if (ret == 0) {
+			free(mutex);
+			*sem = 0;
+		}			
+	}
+	return ret;
+}
+
+int uffs_OSGetTaskId(void)
+{
+	//TODO: ... return current task ID ...
+	return 0;
+}
+
+unsigned int uffs_GetCurDateTime(void)
+{
+	// FIXME: return system time, please modify this for your platform ! 
+	//			or just return 0 if you don't care about file time.
+	time_t tvalue;
+
+	tvalue = time(NULL);
+	
+	return (unsigned int)tvalue;
+}
+
+#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
+static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size)
+{
+	dev = dev;
+	uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size);
+	return malloc(size);
+}
+
+static URET sys_free(struct uffs_DeviceSt *dev, void *p)
+{
+	dev = dev;
+	free(p);
+	return U_SUCC;
+}
+
+void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator)
+{
+	allocator->malloc = sys_malloc;
+	allocator->free = sys_free;
+}
+#endif
+
+
+/* debug message output throught 'printf' */
+static void output_dbg_msg(const char *msg);
+static struct uffs_DebugMsgOutputSt m_dbg_ops = {
+	output_dbg_msg,
+	NULL,
+};
+
+static void output_dbg_msg(const char *msg)
+{
+	printf("%s", msg);
+}
+
+void uffs_SetupDebugOutput(void)
+{
+	uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY);
+}

+ 317 - 0
components/dfs/filesystems/uffs/src/platform/win32/uffs_config.h

@@ -0,0 +1,317 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/** 
+ * \file uffs_config.h
+ * \brief basic configuration of uffs
+ * \author Ricky Zheng
+ */
+
+#ifndef _UFFS_CONFIG_H_
+#define _UFFS_CONFIG_H_
+
+/**
+ * \def UFFS_MAX_PAGE_SIZE
+ * \note maximum page size UFFS support
+ */
+#define UFFS_MAX_PAGE_SIZE		2048
+
+/**
+ * \def UFFS_MAX_SPARE_SIZE
+ */
+#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8)
+
+/**
+ * \def UFFS_MAX_ECC_SIZE
+ */
+#define UFFS_MAX_ECC_SIZE  ((UFFS_MAX_PAGE_SIZE / 256) * 5)
+
+/**
+ * \def MAX_CACHED_BLOCK_INFO
+ * \note uffs cache the block info for opened directories and files,
+ *       a practical value is 5 ~ MAX_OBJECT_HANDLE
+ */
+#define MAX_CACHED_BLOCK_INFO	50
+
+/** 
+ * \def MAX_PAGE_BUFFERS
+ * \note the bigger value will bring better read/write performance.
+ *       but few writing performance will be improved when this 
+ *       value is become larger than 'max pages per block'
+ */
+#define MAX_PAGE_BUFFERS		40
+
+
+/** 
+ * \def CLONE_BUFFER_THRESHOLD
+ * \note reserve buffers for clone. 1 or 2 should be enough.
+ */
+#define CLONE_BUFFERS_THRESHOLD	2
+
+/**
+ * \def MAX_SPARE_BUFFERS
+ * \note spare buffers are used for lower level flash operations,
+ *		 5 should be enough.
+ */
+#define MAX_SPARE_BUFFERS		5
+
+
+/**
+ * \def MAX_DIRTY_PAGES_IN_A_BLOCK 
+ * \note this value should be between '2' and the lesser of
+ *		 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1).
+ *
+ *       the smaller the value the frequently the buffer will be flushed.
+ */
+#define MAX_DIRTY_PAGES_IN_A_BLOCK	32
+
+/**
+ * \def CONFIG_ENABLE_UFFS_DEBUG_MSG
+ * \note Enable debug message output. You must call uffs_InitDebugMessageOutput()
+ *      to initialize debug apart from enable debug feature.
+ */
+#define CONFIG_ENABLE_UFFS_DEBUG_MSG
+
+/**
+ * \def CONFIG_USE_GLOBAL_FS_LOCK
+ * \note use global lock instead of per-device lock.
+ *       this is required if you use fd APIs in multi-thread environment.
+ */
+#define CONFIG_USE_GLOBAL_FS_LOCK
+
+
+/**
+ * \def CONFIG_USE_PER_DEVICE_LOCK
+ * \note use per-device lock.
+ *		 this is required if you use fs APIs in multi-thread environment.
+ */
+//#define CONFIG_USE_PER_DEVICE_LOCK
+
+
+
+/**
+ * \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR
+ * \note uffs will use static memory allocator if this is defined.
+ *       to use static memory allocator, you need to provide memory
+ *       buffer when creating uffs_Device.
+ *
+ *       use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size.
+ */
+#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0
+
+/**
+ * \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR
+ * \note  using system platform's 'malloc' and 'free'.
+ */
+#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1
+
+
+
+/** 
+ * \def CONFIG_FLUSH_BUF_AFTER_WRITE
+ * \note UFFS will write all data directly into flash in 
+ *       each 'write' call if you enable this option.
+ *       (which means lesser data lost when power failure but
+ *		 poorer writing performance).
+ *		 It's not recommended to open this define for normal applications.
+ */
+//#define CONFIG_FLUSH_BUF_AFTER_WRITE
+
+
+/**
+ * \def CONFIG_UFFS_AUTO_LAYOUT_MTD_COMP
+ * \note Use Linux MTD compatiable spare placement for UFFS_LAYOUT_AUTO,
+ *       only valid for page data size 512 or 2048.
+ */
+//#define CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME
+
+
+/** 
+ * \def MAX_OBJECT_HANDLE
+ * maximum number of object handle 
+ */
+#define MAX_OBJECT_HANDLE	50
+#define FD_SIGNATURE_SHIFT	6
+
+
+/**
+ * \def MAX_DIR_HANDLE
+ * maximum number of uffs_DIR
+ */
+#define MAX_DIR_HANDLE	10
+
+/**
+ * \def MINIMUN_ERASED_BLOCK
+ *  UFFS will not allow appending or creating new files when the free/erased block
+ *  is lower then MINIMUN_ERASED_BLOCK.
+ */
+#define MINIMUN_ERASED_BLOCK 2
+
+/**
+ * \def CONFIG_CHANGE_MODIFY_TIME
+ * \note If defined, closing a file which is opened for writing/appending will
+ *       update the file's modify time as well. Disable this feature will save a
+ *       lot of writing activities if you frequently open files for write and close it.
+ */
+//#define CONFIG_CHANGE_MODIFY_TIME
+
+
+/**
+ * \def CONFIG_ENABLE_BAD_BLOCK_VERIFY
+ * \note allow erase and verify block marked as 'bad' when format UFFS partition.
+ *		it's not recommended for most NAND flash.
+ */
+#define CONFIG_ENABLE_BAD_BLOCK_VERIFY
+
+/**
+ * \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
+ * \note erase block again before mark bad block
+ */
+//#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
+
+/**
+ * \def CONFIG_PAGE_WRITE_VERIFY
+ * \note verify page data after write, for extra safe data storage.
+ */
+#define CONFIG_PAGE_WRITE_VERIFY
+
+/**
+ * \def CONFIG_BAD_BLOCK_POLICY_STRICT
+ * \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found;
+ *       otherwise, UFFS report bad block only when ECC failed or reported
+ *		 by low level flash driver.
+ *
+ * \note Enable this will ensure your data always be stored on completely good blocks.
+ */
+#define CONFIG_BAD_BLOCK_POLICY_STRICT
+
+
+/**
+ * \def CONFIG_ENABLE_PAGE_DATA_CRC
+ * \note If this is enabled, UFFS save page data CRC16 sum in mini header,
+ *       it provides extra protection for data integrity.
+ */
+//#define CONFIG_ENABLE_PAGE_DATA_CRC
+
+
+/** micros for calculating buffer sizes */
+
+/**
+ *	\def UFFS_BLOCK_INFO_BUFFER_SIZE
+ *	\brief calculate memory bytes for block info caches
+ */
+#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block)	\
+			(											\
+				(										\
+					sizeof(uffs_BlockInfo) +			\
+					sizeof(uffs_PageSpare) * n_pages_per_block \
+				 ) * MAX_CACHED_BLOCK_INFO				\
+			)
+
+/**
+ *	\def UFFS_PAGE_BUFFER_SIZE
+ *	\brief calculate memory bytes for page buffers
+ */
+#define UFFS_PAGE_BUFFER_SIZE(n_page_size)	\
+			(								\
+				(							\
+					sizeof(uffs_Buf) + n_page_size	\
+				) * MAX_PAGE_BUFFERS		\
+			)
+
+/**
+ *	\def UFFS_TREE_BUFFER_SIZE
+ *	\brief calculate memory bytes for tree nodes
+ */
+#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks)
+
+
+#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE)
+
+
+/**
+ *	\def UFFS_STATIC_BUFF_SIZE
+ *	\brief calculate total memory usage of uffs system
+ */
+#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \
+			(		\
+				UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \
+				UFFS_PAGE_BUFFER_SIZE(n_page_size) + \
+				UFFS_TREE_BUFFER_SIZE(n_blocks) + \
+				UFFS_SPARE_BUFFER_SIZE \
+			 )
+
+
+
+/* config check */
+#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3
+#error "MAX_PAGE_BUFFERS is too small"
+#endif
+
+#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2)
+#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2"
+#endif
+
+#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK)
+#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)"
+#endif
+
+#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2)
+#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled."
+#endif
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1
+#error "Please enable ONLY one memory allocator"
+#endif
+
+#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0
+#error "Please enable ONE of memory allocators"
+#endif
+
+#if defined(CONFIG_USE_GLOBAL_FS_LOCK) && defined(CONFIG_USE_PER_DEVICE_LOCK)
+#error "enable either CONFIG_USE_GLOBAL_FS_LOCK or CONFIG_USE_PER_DEVICE_LOCK, not both"
+#endif
+
+#if (MAX_OBJECT_HANDLE > (1 << FD_SIGNATURE_SHIFT))
+#error "Please increase FD_SIGNATURE_SHIFT !"
+#endif
+
+#ifdef WIN32
+# pragma warning(disable : 4996)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4214)
+# pragma warning(disable : 4127)
+# pragma warning(disable : 4389)
+# pragma warning(disable : 4100)
+#endif
+
+#endif

+ 148 - 0
components/dfs/filesystems/uffs/src/platform/win32/uffs_os.c

@@ -0,0 +1,148 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file uffs_os.c
+ * \brief Emulation on win32 host
+ * \author Ricky Zheng
+ */
+
+#include "uffs_config.h"
+#include "uffs/uffs_os.h"
+#include "uffs/uffs_public.h"
+#include <memory.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <windows.h>
+
+#define PFX "os  : "
+
+int uffs_SemCreate(OSSEM *sem)
+{
+	HANDLE mutex = CreateMutex( 
+        NULL,		// default security attributes
+        FALSE,		// initially not owned
+        NULL);		// unnamed mutex
+
+	if (mutex == NULL) {
+		printf("Create mutex failed !\n");
+		return -1;
+	}
+	else {
+		*sem = (OSSEM)mutex;
+	}
+
+	return 0;
+}
+
+int uffs_SemWait(OSSEM sem)
+{
+	DWORD result;
+
+	result =  WaitForSingleObject( 
+            (HANDLE)sem,    // handle to mutex
+            INFINITE);		// no time-out interval
+
+	return result == WAIT_ABANDONED ? -1 : 0;
+}
+
+int uffs_SemSignal(OSSEM sem)
+{
+	return ReleaseMutex((HANDLE)sem) ? 0 : -1;
+}
+
+int uffs_SemDelete(OSSEM *sem)
+{
+	if (CloseHandle((HANDLE)(*sem))) {
+		*sem = 0;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+int uffs_OSGetTaskId(void)
+{
+	return 0;
+}
+
+unsigned int uffs_GetCurDateTime(void)
+{
+	// FIXME: return system time, please modify this for your platform ! 
+	//			or just return 0 if you don't care about file time.
+	time_t tvalue;
+
+	tvalue = time(NULL);
+	
+	return (unsigned int)tvalue;
+}
+
+#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
+static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size)
+{
+	dev = dev;
+	uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size);
+	return malloc(size);
+}
+
+static URET sys_free(struct uffs_DeviceSt *dev, void *p)
+{
+	dev = dev;
+	free(p);
+	return U_SUCC;
+}
+
+void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator)
+{
+	allocator->malloc = sys_malloc;
+	allocator->free = sys_free;
+}
+#endif
+
+
+/* debug message output throught 'printf' */
+static void output_dbg_msg(const char *msg);
+static struct uffs_DebugMsgOutputSt m_dbg_ops = {
+	output_dbg_msg,
+	NULL,
+};
+
+static void output_dbg_msg(const char *msg)
+{
+	printf("%s", msg);
+}
+
+void uffs_SetupDebugOutput(void)
+{
+	uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY);
+}

+ 37 - 0
components/dfs/filesystems/uffs/src/test/api_test/CMakeLists.txt

@@ -0,0 +1,37 @@
+SET (libapitest_server_SRCS 
+		api_test.c
+		api_test.h
+	)
+
+SET (libapitest_client_SRCS
+		api_test.c
+		api_test.h
+		api_test_client_wrapper.c
+		${uffs_SOURCE_DIR}/src/uffs/uffs_crc.c
+	)
+
+IF (UNIX)
+	SET (libapitest_server_SRCS ${libapitest_server_SRCS} api_test_server_posix.c)
+	SET (libapitest_client_SRCS ${libapitest_client_SRCS} api_test_client_posix.c)
+ENDIF()
+
+IF (WIN32)
+	SET (libapitest_server_SRCS ${libapitest_server_SRCS} api_test_server_win32.c)
+	SET (libapitest_client_SRCS ${libapitest_client_SRCS} api_test_client_win32.c)
+ENDIF()
+
+SET (libapitest_sqlite3_SRCS
+		${libapitest_client_SRCS}
+		os_uffs.c
+		os_uffs.h
+	)
+
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
+ADD_LIBRARY(apitest_server STATIC ${libapitest_server_SRCS})
+ADD_LIBRARY(apitest_client STATIC ${libapitest_client_SRCS})
+IF (UNIX)
+	ADD_LIBRARY(apitest_sqlite3 SHARED ${libapitest_sqlite3_SRCS})
+ENDIF()
+
+
+

+ 1168 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test.c

@@ -0,0 +1,1168 @@
+/*
+This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+UFFS is free software; you can redistribute it and/or modify it under
+the GNU Library General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+UFFS 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
+or GNU Library General Public License, as applicable, for more details.
+
+You should have received a copy of the GNU General Public License
+and GNU Library General Public License along with UFFS; if not, write
+to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA  02110-1301, USA.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered
+by the GNU General Public License. However the source code for this
+file must still be made available in accordance with section (3) of
+the GNU General Public License v2.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+
+/**
+* \file api_test.c
+* \brief API test server public functions 
+* \author Ricky Zheng, created in 16 Dec, 2011 
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "uffs/uffs_crc.h"
+#include "api_test.h"
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG printf
+#else
+#define DBG(...)
+#endif
+
+static struct uffs_ApiSrvIoSt *m_io = NULL;
+static int m_api_stat[UFFS_API_CMD_LAST + 1] = {0};
+
+int apisrv_setup_io(struct uffs_ApiSrvIoSt *io)
+{
+	m_io = io;
+	return 0;
+}
+
+//
+// unload parameters from message.
+// parameters list:
+//  param1, size1, param2, size2, ..., NULL
+// size: maximum size of parameter.
+//
+static int apisrv_unload_params(struct uffs_ApiSrvMsgSt *msg, ...)
+{
+    int ret = 0;
+    int len, size;
+	u32 n;
+    u8 *p;
+    u8 *data;
+    struct uffs_ApiSrvHeaderSt *header = &msg->header;
+
+    va_list args;
+
+    va_start(args, msg);
+
+    for (n = 0, data = msg->data; n < header->n_params; n++) {
+        p = va_arg(args, void *);
+        if (p == NULL)
+            break;
+		len = va_arg(args, int);
+		size = header->param_size[n];
+		if (size > len) {
+			printf("cmd %d unload param %d overflow (max %d but %d)\n",
+					header->cmd, n, len, size);
+			ret = -1;
+			break;
+		}
+        memcpy(p, data, size);
+        data += size;
+    }
+
+    if (n != header->n_params) {
+        printf("cmd %d unload params failed!\n", header->cmd);
+        ret = -1;
+    }
+
+    if (data - msg->data != header->data_len) {
+        printf("cmd %d unload params failed! data len mismatched.\n", header->cmd);
+        ret = -1;
+    }
+
+    va_end(args);
+
+    return ret;
+}
+
+// load response data. the parameter list: (&param1, size1, &param2, size2, .... NULL)
+static int apisrv_make_message(struct uffs_ApiSrvMsgSt *msg, ...)
+{
+    int ret = 0;
+    u32 n;
+    u32 len, size;
+    struct uffs_ApiSrvHeaderSt *header = &msg->header;
+    u8 *p;
+    u8 * params[UFFS_API_MAX_PARAMS];
+
+    va_list args;
+
+    va_start(args, msg);
+
+    for (n = 0, len = 0; n < UFFS_API_MAX_PARAMS; n++) {
+        p = va_arg(args, u8 *);
+        if (p == NULL)  // terminator
+            break;
+        params[n] = p;
+		size = va_arg(args, size_t);
+		if (size > header->return_size[n]) {
+			printf("WARNING: cmd %d make message param %d expect %d but %d, truncated.\n", header->cmd, n, header->return_size[n], size);
+			size = header->return_size[n];
+		}
+	    header->param_size[n] = size;
+        len += header->param_size[n];
+    }
+    header->n_params = n;
+
+    va_end(args);
+
+	// free buffer if already allocated.
+	if (msg->data)
+		free(msg->data);
+
+	msg->data = (u8 *)malloc(len);
+	if (msg->data == NULL) {
+		printf("Fail to malloc %d bytes\n", len);
+		ret = -1;
+		goto ext;
+	}
+	header->data_len = len;
+
+    for (n = 0, p = msg->data; n < header->n_params; n++) {
+        memcpy(p, params[n], header->param_size[n]);
+        p += header->param_size[n];
+    }
+
+ext:
+
+    return ret;
+}
+
+
+// calculate crc, send message.
+static int apisrv_send_message(int fd, struct uffs_ApiSrvMsgSt *msg)
+{
+    int ret;
+
+    msg->header.data_crc = uffs_crc16sum(msg->data, msg->header.data_len);
+    msg->header.header_crc = uffs_crc16sum(&msg->header, sizeof(struct uffs_ApiSrvHeaderSt));
+
+    ret = m_io->write(fd, &msg->header, sizeof(struct uffs_ApiSrvHeaderSt));
+    if (ret < 0) {
+        perror("Sending header failed");
+    }
+    else {
+        ret = m_io->write(fd, msg->data, msg->header.data_len);
+        if (ret < 0) {
+            perror("Sending data failed");
+        }
+    }
+
+    return ret;
+}
+
+static int check_apisrv_header(struct uffs_ApiSrvHeaderSt *header)
+{
+    return 0;
+}
+
+static int check_apisrv_msg(struct uffs_ApiSrvMsgSt *msg)
+{
+    return 0;
+}
+
+static int apisrv_read_message(int fd, struct uffs_ApiSrvMsgSt *msg)
+{
+	int ret = -1;
+	struct uffs_ApiSrvHeaderSt *header = &msg->header;
+	u8 *data = NULL;
+
+	memset(msg, 0, sizeof(struct uffs_ApiSrvMsgSt));
+	ret = m_io->read(fd, header, sizeof(struct uffs_ApiSrvHeaderSt));
+	if (ret < 0) {
+		printf("Read header failed!\n");
+		goto ext;
+	}
+
+	ret = check_apisrv_header(header);
+	if (ret < 0)
+		goto ext;
+
+	if (header->data_len > 0) {
+		data = (u8 *)malloc(header->data_len);
+		if (data == NULL) {
+			printf("malloc %d bytes failed\n", header->data_len);
+			goto ext;
+		}
+
+		msg->data = data;
+		ret = m_io->read(fd, data, header->data_len);
+		if (ret < 0) {
+			printf("read data failed\n");
+			goto ext;
+		}
+	}
+
+	ret = check_apisrv_msg(msg);
+	if (ret < 0) {
+		printf("check data CRC failed!\n");
+		goto ext;
+	}
+
+ext:
+	return ret;	
+}
+
+static int apisrv_free_message(struct uffs_ApiSrvMsgSt *msg)
+{
+	if (msg && msg->data) {
+		free(msg->data);
+		msg->data = NULL;
+	}
+
+	return 0;
+}
+
+static int process_cmd(int sock, struct uffs_ApiSrvMsgSt *msg, struct uffs_ApiSt *api)
+{
+    struct uffs_ApiSrvHeaderSt *header = &msg->header;
+    int ret = 0;
+    char name[256];
+
+    //DBG("Received cmd = %d, params %d, data_len = %d\n", UFFS_API_CMD(header), header->n_params, header->data_len);
+
+    switch(UFFS_API_CMD(header)) {
+    case UFFS_API_GET_VER_CMD:
+    {
+        int val;
+        val = api->uffs_version();
+		DBG("uffs_version() = 0x%08x\n", val);
+        ret = apisrv_make_message(msg, &val, sizeof(val), NULL);
+        break;
+    }
+    case UFFS_API_OPEN_CMD:
+    {
+        int open_mode;
+		int fd;
+        ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), &open_mode, sizeof(open_mode), NULL);
+		if (ret == 0) {
+			fd = api->uffs_open(name, open_mode);
+			DBG("uffs_open(name = \"%s\", open_mode = 0x%x) = %d\n", name, open_mode, fd);
+			ret = apisrv_make_message(msg, &fd, sizeof(fd), -1, 0, -1, 0, NULL);
+		}
+        break;
+    }
+    case UFFS_API_CLOSE_CMD:
+	{
+		int fd, r;
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), NULL);
+		if (ret == 0) {
+			r = api->uffs_close(fd);
+			DBG("uffs_close(fd = %d) = %d\n", fd, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_READ_CMD:
+	{
+		int fd, r, len;
+		void *buf = NULL;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), -1, 0, &len, sizeof(len), NULL);
+		if (ret == 0) {
+			if (len > 0) {
+				buf = malloc(len);
+				if (buf == NULL) {
+					printf("malloc %d bytes failed.\n", len);
+					ret = -1;
+				}
+			}
+
+			if (ret == 0) {
+				r = api->uffs_read(fd, buf, len);
+				DBG("uffs_read(fd = %d, buf = {...}, len = %d) = %d\n", fd, len, r);
+				ret = apisrv_make_message(msg, &r, sizeof(r),
+											-1, 0,	/* fd */
+											buf ? buf : (void *)-1, buf ? len : 0,	/* buf */
+											-1, 0,	/* len */
+											NULL);
+			}
+		}
+
+		if (buf)
+			free(buf);
+
+        break;
+	}
+    case UFFS_API_WRITE_CMD:
+	{
+		int fd, r, len;
+		void *buf = NULL;
+
+		buf = malloc(header->data_len);
+		if (buf == NULL) {
+			printf("malloc %d failed.\n", header->data_len);
+			ret = -1;
+		}
+		else {
+			ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), buf, header->data_len, &len, sizeof(len), NULL);
+			if (ret == 0) {
+				r = api->uffs_write(fd, buf, len);
+				DBG("uffs_write(fd = %d, buf = {...}, len = %d) = %d\n", fd, len, r);
+				ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, -1, 0, -1, 0, NULL);
+			}
+			free(buf);
+		}
+
+        break;
+	}
+    case UFFS_API_FLUSH_CMD:
+	{
+		int fd, r;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), NULL);
+		if (ret == 0) {
+			r = api->uffs_flush(fd);
+			DBG("uffs_flush(fd = %d) = %d\n", fd, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+
+        break;
+	}
+    case UFFS_API_SEEK_CMD:
+	{
+		int fd, origin;
+		i32 r, offset;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), &offset, sizeof(offset), &origin, sizeof(origin), NULL);
+		if (ret == 0) {
+			r = (i32) api->uffs_seek(fd, (long)offset, origin);
+			DBG("uffs_seek(fd = %d, offset = %d, origin = %d) = %d\n", fd, offset, origin, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, -1, 0, -1, 0, NULL);
+		}
+
+        break;
+	}
+    case UFFS_API_TELL_CMD:
+	{
+		int fd;
+		i32 r;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), NULL);
+		if (ret == 0) {
+			r = (i32) api->uffs_tell(fd);
+			DBG("uffs_tell(fd = %d) = %d\n", fd, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_EOF_CMD:
+	{
+		int fd, r;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), NULL);
+		if (ret == 0) {
+			r = api->uffs_eof(fd);
+			DBG("uffs_eof(fd = %d) = %d\n", fd, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_RENAME_CMD:
+	{
+		int r;
+		char *oldname = NULL;
+		char *newname = NULL;
+
+		oldname = (char *)malloc(header->data_len);
+		newname = (char *)malloc(header->data_len);
+
+		if (oldname && newname) {
+			ret = apisrv_unload_params(msg, -1, 0, oldname, header->data_len, newname, header->data_len, NULL);
+			if (ret == 0) {
+				r = api->uffs_rename(oldname, newname);
+				DBG("uffs_rename(old = \"%s\", new = \"%s\") = %d\n", oldname, newname, r);
+				ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, -1, 0, NULL);
+			}
+		}
+		else {
+			printf("malloc %d bytes failed.\n", header->data_len);
+			ret = -1;
+		}
+
+		if (oldname)
+			free(oldname);
+		if (newname)
+			free(newname);
+
+        break;
+	}
+    case UFFS_API_REMOVE_CMD:
+	{
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = api->uffs_remove(name);
+			DBG("uffs_remove(name = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_FTRUNCATE_CMD:
+	{
+		int fd, r;
+		i32 remain;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), &remain, sizeof(remain), NULL);
+		if (ret == 0) {
+			r = api->uffs_ftruncate(fd, (long)remain);
+			DBG("uffs_ftruncate(fd = %d, remain = %d) = %d\n", fd, remain, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_MKDIR_CMD:
+	{
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = api->uffs_mkdir(name);
+			DBG("uffs_mkdir(name = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_RMDIR_CMD:
+	{
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = api->uffs_rmdir(name);
+			DBG("uffs_rmdir(name= \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_STAT_CMD:
+    case UFFS_API_LSTAT_CMD:
+	{
+		struct uffs_stat buf;
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), -1, 0, NULL);
+		if (ret == 0) {
+			r = api->uffs_stat(name, &buf);
+			DBG("uffs_stat(name = \"%s\", buf = {...}) = %d\n", name, r); 
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, &buf, sizeof(struct uffs_stat), NULL);
+		}
+        break;
+	}
+    case UFFS_API_FSTAT_CMD:
+	{
+		int fd, r;
+		struct uffs_stat buf;
+
+		ret = apisrv_unload_params(msg, -1, 0, &fd, sizeof(fd), -1, 0, NULL);
+		if (ret == 0) {
+			r = api->uffs_fstat(fd, &buf);
+			DBG("uffs_fstat(fd = %d, buf = {...}) = %d\n", fd, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, &buf, sizeof(struct uffs_stat), NULL);
+		}
+        break;
+	}
+    case UFFS_API_OPEN_DIR_CMD:
+	{
+		uffs_DIR *dirp;
+		
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			dirp = api->uffs_opendir(name);
+			DBG("uffs_opendir(name = \"%s\") = %p\n", name, dirp);
+			ret = apisrv_make_message(msg, &dirp, sizeof(uffs_DIR *), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_CLOSE_DIR_CMD:
+	{
+		uffs_DIR *dirp;
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, &dirp, sizeof(uffs_DIR *), NULL);
+		if (ret == 0) {
+			r = api->uffs_closedir(dirp);
+			DBG("uffs_closedir(dirp = %p) = %d\n", dirp, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_READ_DIR_CMD:
+	{
+		uffs_DIR *dirp;
+		struct uffs_dirent *dent;
+
+		ret = apisrv_unload_params(msg, -1, 0, &dirp, sizeof(uffs_DIR *), NULL);
+		if (ret == 0) {
+			dent = api->uffs_readdir(dirp);
+			DBG("uffs_readdir(dirp = %p) = %s\n", dirp, dent ? "{...}" : "NULL");
+			ret = apisrv_make_message(msg, dent, sizeof(struct uffs_dirent), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_REWIND_DIR_CMD:
+	{
+		uffs_DIR *dirp;
+
+		ret = apisrv_unload_params(msg, -1, 0, &dirp, sizeof(uffs_DIR *), NULL);
+		if (ret == 0) {
+			api->uffs_rewinddir(dirp);
+			DBG("uffs_rewinddir(dirp = %p)\n", dirp);
+			ret = apisrv_make_message(msg, 0, -1, 0, -1, NULL);
+		}
+        break;
+	}
+    case UFFS_API_GET_ERR_CMD:
+	{
+		int r;
+
+		r = api->uffs_get_error();
+		DBG("uffs_get_error() = %d\n", r);
+		ret = apisrv_make_message(msg, &r, sizeof(r), NULL);
+
+        break;
+	}
+    case UFFS_API_SET_ERR_CMD:
+	{
+		int err, r;
+
+		ret = apisrv_unload_params(msg, -1, 0, &err, sizeof(err), NULL);
+		if (ret == 0) {
+			r = api->uffs_set_error(err);
+			DBG("uffs_set_error(err = %d) = %d\n", err, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_FORMAT_CMD:
+	{
+		int r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = api->uffs_format(name);
+			DBG("uffs_format(mount = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_SPACE_TOTAL_CMD:
+	{
+		i32 r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = (i32) api->uffs_space_total(name);
+			DBG("uffs_space_total(mount = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_SPACE_FREE_CMD:
+	{
+		i32 r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = (i32) api->uffs_space_free(name);
+			DBG("uffs_space_free(mount = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+    case UFFS_API_SPACE_USED_CMD:
+	{
+		i32 r;
+
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			r = (i32) api->uffs_space_used(name);
+			DBG("uffs_space_used(mount = \"%s\") = %d\n", name, r);
+			ret = apisrv_make_message(msg, &r, sizeof(r), -1, 0, NULL);
+		}
+        break;
+	}
+	case UFFS_API_FLUSH_ALL_CMD:
+	{
+		ret = apisrv_unload_params(msg, -1, 0, name, sizeof(name), NULL);
+		if (ret == 0) {
+			api->uffs_flush_all(name);
+			DBG("uffs_flush_all(mount = \"%s\")\n", name);
+			ret = apisrv_make_message(msg, -1, 0, -1, 0, NULL);
+		}
+		break;
+	}
+    default:
+        printf("Unknown command %x\n", header->cmd);
+        ret = -1;
+        break;
+    }
+
+	if (ret == 0) {
+		// we might need a mutex here if we using multi-thread server,
+		// but this probably ok since it just for statistic purpose.
+		m_api_stat[UFFS_API_CMD(header)]++;
+	}
+
+	if (ret == 0)
+		ret = apisrv_send_message(sock, msg);
+
+    return ret;
+}
+
+int apisrv_serve(int fd, struct uffs_ApiSt *api)
+{
+    int ret = 0;
+    struct uffs_ApiSrvMsgSt msg;
+
+	ret = apisrv_read_message(fd, &msg);
+
+    if (ret == 0)
+        ret = process_cmd(fd, &msg, api);
+
+	apisrv_free_message(&msg);
+
+    return ret;
+}
+
+void apisrv_print_stat(void)
+{
+	int i;
+	printf("--- API call stat ---\n");
+	for (i = 0; i <= UFFS_API_CMD_LAST; i++) {
+		printf("API %2d: %d\n", i, m_api_stat[i]);
+	}
+	printf("--- END ---\n");
+}
+
+/**
+ * variable parameters list:
+ *  &ret, size_ret, return_size_ret, &param1, size_param1, return_size_param1, &param2, size_param2, return_size_param2... NULL
+ **/
+static int call_remote(int cmd, ...)
+{
+	struct uffs_ApiSrvMsgSt msg;
+	struct uffs_ApiSrvHeaderSt *header = &msg.header;
+	int ret = -1, fd = -1;
+	u32 n = 0;
+	u8 *p;
+	u32 len, size;
+	u8 * params[UFFS_API_MAX_PARAMS];
+	u32 return_size[UFFS_API_MAX_PARAMS];
+	u32 n_params = 0;
+	va_list args;
+
+	memset(&msg, 0, sizeof(struct uffs_ApiSrvMsgSt));
+
+	fd = m_io->open(m_io->addr);
+	if (fd < 0) 
+		goto ext;
+
+	header->cmd = cmd;
+
+	// parse tparameter list
+	va_start(args, cmd);
+	for (n = 0, len = 0; n < UFFS_API_MAX_PARAMS; n++) {
+		p = va_arg(args, u8 *);
+		if (p == NULL)
+			break;
+		params[n] = p;
+		size = va_arg(args, int);
+		header->param_size[n] = size;
+		header->return_size[n] = va_arg(args, int);
+		return_size[n] = header->return_size[n];
+		len += size;
+	}
+	va_end(args);
+
+	n_params = n;
+	header->n_params = n;
+	//DBG("C: cmd %d, params %d, data_len %d\n", cmd, n, len);
+
+	msg.data = (u8 *) malloc(len);
+	if (msg.data == NULL) {
+		printf("Fail to malloc %d bytes\n", len);
+		goto ext;
+	}
+	header->data_len = len;
+
+	// now, load parameters
+	for (n = 0, len = 0; n < n_params; n++) {
+		if (header->param_size[n] > 0) {
+			memcpy(msg.data + len, params[n], header->param_size[n]);
+			len += header->param_size[n];
+		}
+	}
+
+	// send
+	ret = apisrv_send_message(fd, &msg);
+	if (ret < 0)
+		goto ext;
+
+	// free data pointer
+	apisrv_free_message(&msg);
+
+	// receive response
+	ret = apisrv_read_message(fd, &msg);
+	if (ret < 0)
+		goto ext;
+
+	if (header->n_params != n_params) {
+		printf("Response %d parameters but expect %d\n", header->n_params, n_params);
+		ret = -1;
+		goto ext;
+	}
+
+	// now, unload return parameters
+	for (n = 0, p = msg.data; n < header->n_params; n++) {
+		size = header->param_size[n];
+		if (return_size[n] != header->return_size[n]) {
+			printf("WARNING: cmd %d param %d return size not kept ? expect %d but %d\n", header->cmd, n, return_size[n], header->return_size[n]);
+		}
+		memcpy(params[n], p, size > return_size[n] ? return_size[n] : size);
+		if (size > return_size[n]) {
+			printf("WARNING: cmd %d return param %d overflow, expect %d but %d\n", header->cmd, n, return_size[n], size);
+		}
+		p += size;
+	}
+	
+ext:
+	apisrv_free_message(&msg);
+	if (fd >= 0)
+		m_io->close(fd);
+
+	return ret;
+
+}
+
+static int _uffs_version(void)
+{
+	int version = 0;
+	int ret = -1;
+
+	ret = call_remote(UFFS_API_GET_VER_CMD, &version, 0, sizeof(version), NULL);
+
+	return ret < 0 ? 0 : version;
+}
+
+static int _uffs_open(const char *name, int oflag, ...)
+{
+	int fd = -1;
+	int ret = -1;
+
+	ret = call_remote(UFFS_API_OPEN_CMD, &fd, 0, sizeof(fd), 
+						name, strlen(name) + 1, 0, 
+						&oflag, sizeof(oflag), 0, 
+						NULL);
+
+	return ret < 0 ? ret : fd;
+}
+
+static int _uffs_close(int fd)
+{
+	int r = -1;
+	int ret = -1;
+
+	ret = call_remote(UFFS_API_CLOSE_CMD, &r, 0, sizeof(r), &fd, sizeof(fd), 0, NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_read(int fd, void *buf, int len)
+{
+	int r = -1, ret = -1;
+
+	if (buf) {
+		ret = call_remote(UFFS_API_READ_CMD, &r, 0, sizeof(r), 
+						&fd, sizeof(fd), 0, 
+						buf, 0, len, 
+						&len, sizeof(len), 0,
+						NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_write(int fd, const void *buf, int len)
+{
+	int r = -1, ret = -1;
+
+	if (buf) {
+		ret = call_remote(UFFS_API_WRITE_CMD, &r, 0, sizeof(r),
+						&fd, sizeof(fd), 0,
+						buf, len, 0,
+						&len, sizeof(len), 0,
+						NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_flush(int fd)
+{
+	int r = -1, ret = -1;
+
+	ret = call_remote(UFFS_API_FLUSH_CMD, &r, 0, sizeof(r),
+						&fd, sizeof(fd), 0,
+						NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static long _uffs_seek(int fd, long offset, int origin)
+{
+	i32 r_32bit = -1;
+	int ret = -1;
+
+	i32 offset_32bit = (i32)offset;
+
+	ret = call_remote(UFFS_API_SEEK_CMD, &r_32bit, 0, sizeof(r_32bit),
+						&fd, sizeof(fd), 0,
+						&offset_32bit, sizeof(offset_32bit), 0,	// only send 32bit over the network
+						&origin, sizeof(origin), 0,
+						NULL);
+
+	return ret < 0 ? -1L : (long)r_32bit;
+}
+
+static long _uffs_tell(int fd)
+{
+	int ret = -1;
+	i32 r_32bit = -1;
+
+	ret = call_remote(UFFS_API_TELL_CMD, &r_32bit, 0, sizeof(r_32bit),
+						&fd, sizeof(fd), 0,
+						NULL);
+
+	return ret < 0 ? -1L : (long)r_32bit;
+}
+
+static int _uffs_eof(int fd)
+{
+	int r = -1, ret = -1;
+
+	ret = call_remote(UFFS_API_EOF_CMD, &r, 0, sizeof(r),
+						&fd, sizeof(fd), 0,
+						NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_rename(const char *oldname, const char *newname)
+{
+	int r = -1, ret = -1;
+
+	if (oldname && newname) {
+		ret = call_remote(UFFS_API_RENAME_CMD, &r, 0, sizeof(r),
+							oldname, strlen(oldname) + 1, 0,
+							newname, strlen(newname) + 1, 0,
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_remove(const char *name)
+{
+	int ret = -1, r = -1;
+
+	if (name) {
+		ret = call_remote(UFFS_API_REMOVE_CMD, &r, 0, sizeof(r),
+							name, strlen(name) + 1, 0,
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_ftruncate(int fd, long remain)
+{
+	int r = -1, ret = -1;
+	i32 remain_32bit = (i32)remain;
+
+	ret = call_remote(UFFS_API_FTRUNCATE_CMD, &r, 0, sizeof(r),
+						&fd, sizeof(fd), 0,
+						&remain_32bit, sizeof(remain_32bit), 0,
+						NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_mkdir(const char *name, ...)
+{
+	int r = -1, ret = -1;
+
+	if (name) {
+		ret = call_remote(UFFS_API_MKDIR_CMD, &r, 0, sizeof(r),
+							name, strlen(name) + 1, 0,
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_rmdir(const char *name)
+{
+	int r = -1, ret = -1;
+
+	if (name) {
+		ret = call_remote(UFFS_API_RMDIR_CMD, &r, 0, sizeof(r),
+							name, strlen(name) + 1, 0,
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_stat(const char *name, struct uffs_stat *buf)
+{
+	int r = -1, ret = -1;
+
+	if (name && buf) {
+		ret = call_remote(UFFS_API_STAT_CMD, &r, 0, sizeof(r),
+							name, strlen(name) + 1, 0,
+							buf, 0, sizeof(struct uffs_stat),
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_lstat(const char *name, struct uffs_stat *buf)
+{
+	int r = -1, ret = -1;
+
+	if (name && buf) {
+		ret = call_remote(UFFS_API_LSTAT_CMD, &r, 0, sizeof(r),
+							name, strlen(name) + 1, 0,
+							buf, 0, sizeof(struct uffs_stat),
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_fstat(int fd, struct uffs_stat *buf)
+{
+	int r = -1, ret = -1;
+
+	if (buf) {
+		ret = call_remote(UFFS_API_FSTAT_CMD, &r, 0, sizeof(r),
+							&fd, sizeof(fd), 0,
+							buf, 0, sizeof(struct uffs_stat),
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+static uffs_DIR * _uffs_opendir(const char *path)
+{
+	uffs_DIR *dirp = NULL;
+	int ret = -1;
+
+	if (path) {
+		ret = call_remote(UFFS_API_OPEN_DIR_CMD, &dirp, 0, sizeof(uffs_DIR *),
+							path, strlen(path) + 1, 0,
+							NULL);
+	}
+
+	return ret < 0 ? NULL : dirp;
+}
+
+static int _uffs_closedir(uffs_DIR *dirp)
+{
+	int r = -1, ret = -1;
+
+	if (dirp) {
+		ret = call_remote(UFFS_API_CLOSE_DIR_CMD, &r, 0, sizeof(r),
+							&dirp, sizeof(uffs_DIR *), 0,
+							NULL);
+	}
+
+	return ret < 0 ? ret : r;
+}
+
+/**
+ * Note: this is not a thread-safe but we have advantage of not calling 'free' after ...
+ */
+static struct uffs_dirent * _uffs_readdir(uffs_DIR *dirp)
+{
+	static struct uffs_dirent dirent_cache[256];
+	static unsigned char pos = 0;
+
+	int ret = -1;
+	struct uffs_dirent *dent = NULL;
+
+	if (dirp) {
+		dent = &dirent_cache[pos++]; // change 'pos++' to atomic can make this function thread-safe... 
+		ret = call_remote(UFFS_API_READ_DIR_CMD, dent, 0, sizeof(struct uffs_dirent),
+							&dirp, sizeof(uffs_DIR *), 0,
+							NULL);
+	}
+
+	return ret < 0 ? NULL : dent;
+}
+
+static void _uffs_rewinddir(uffs_DIR *dirp)
+{
+	if (dirp) {
+		call_remote(UFFS_API_REWIND_DIR_CMD, -1, 0, 0,
+						&dirp, sizeof(uffs_DIR *), 0,
+						NULL);
+	}
+}
+
+static int _uffs_get_error(void)
+{
+	int r = -1, ret = -1;
+
+	ret = call_remote(UFFS_API_GET_ERR_CMD, &r, 0, sizeof(r), NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_set_error(int err)
+{
+	int r = -1, ret = -1;
+
+	ret = call_remote(UFFS_API_SET_ERR_CMD, &r, 0, sizeof(r),
+						&err, sizeof(err), 0,
+						NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static int _uffs_format(const char *mount)
+{
+	int r = -1, ret = -1;
+
+	if (mount)
+		ret = call_remote(UFFS_API_FORMAT_CMD, &r, 0, sizeof(r),
+						mount, strlen(mount) + 1, 0,
+						NULL);
+
+	return ret < 0 ? ret : r;
+}
+
+static long _uffs_space_total(const char *mount)
+{
+	i32 r_32bit = -1;
+	int ret = -1;
+
+	if (mount)
+		ret = call_remote(UFFS_API_SPACE_TOTAL_CMD, &r_32bit, 0, sizeof(r_32bit),
+							mount, strlen(mount) + 1, 0,
+							NULL);
+
+	return ret < 0 ? -1L : (long)r_32bit;
+}
+
+static long _uffs_space_used(const char *mount)
+{
+	i32 r_32bit = -1;
+	int ret = -1;
+
+	if (mount)
+		ret = call_remote(UFFS_API_SPACE_USED_CMD, &r_32bit, 0, sizeof(r_32bit),
+							mount, strlen(mount) + 1, 0,
+							NULL);
+
+	return ret < 0 ? -1L : (long)r_32bit;
+}
+
+static long _uffs_space_free(const char *mount)
+{
+	i32 r_32bit = -1;
+	int ret = -1;
+
+	if (mount)
+		ret = call_remote(UFFS_API_SPACE_FREE_CMD, &r_32bit, 0, sizeof(r_32bit),
+							mount, strlen(mount) + 1, 0,
+							NULL);
+
+	return ret < 0 ? -1L : (long)r_32bit;
+}
+
+static void _uffs_flush_all(const char *mount)
+{
+	if (mount) {
+		call_remote(UFFS_API_FLUSH_ALL_CMD, -1, 0, 0,
+							mount, strlen(mount) + 1, 0,
+							NULL);
+	}
+}
+
+
+static struct uffs_ApiSt m_client_api = {
+	_uffs_version,
+	_uffs_open,
+	_uffs_close,
+	_uffs_read,
+	_uffs_write,
+	_uffs_flush,
+	_uffs_seek,
+	_uffs_tell,
+	_uffs_eof,
+	_uffs_rename,
+	_uffs_remove,
+	_uffs_ftruncate,
+	_uffs_mkdir,
+	_uffs_rmdir,
+	_uffs_stat,
+	_uffs_lstat,
+	_uffs_fstat,
+	_uffs_opendir,
+	_uffs_closedir,
+	_uffs_readdir,
+	_uffs_rewinddir,
+	_uffs_get_error,
+	_uffs_set_error,
+	_uffs_format,
+	_uffs_space_total,
+	_uffs_space_used,
+	_uffs_space_free,
+	_uffs_flush_all,
+};
+
+struct uffs_ApiSt * apisrv_get_client(void)
+{
+	return &m_client_api;
+}
+

+ 150 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test.h

@@ -0,0 +1,150 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file api_srv.h
+ * \brief UFFS API test server definitions 
+ * \author Ricky Zheng, created 16 Dec, 2011
+ */
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_fd.h"
+
+#ifndef _UFFS_API_SRV_H_
+#define _UFFS_API_SRV_H_
+
+#define SRV_PORT        9018
+
+#define UFFS_API_GET_VER_CMD            0
+#define UFFS_API_OPEN_CMD               1
+#define UFFS_API_CLOSE_CMD              2
+#define UFFS_API_READ_CMD               3
+#define UFFS_API_WRITE_CMD              4
+#define UFFS_API_FLUSH_CMD              5
+#define UFFS_API_SEEK_CMD               6
+#define UFFS_API_TELL_CMD               7
+#define UFFS_API_EOF_CMD                8
+#define UFFS_API_RENAME_CMD             9
+#define UFFS_API_REMOVE_CMD             10
+#define UFFS_API_FTRUNCATE_CMD          11
+#define UFFS_API_MKDIR_CMD              12
+#define UFFS_API_RMDIR_CMD              13
+#define UFFS_API_STAT_CMD               14
+#define UFFS_API_LSTAT_CMD              15
+#define UFFS_API_FSTAT_CMD              16
+#define UFFS_API_OPEN_DIR_CMD           17
+#define UFFS_API_CLOSE_DIR_CMD          18
+#define UFFS_API_READ_DIR_CMD           19
+#define UFFS_API_REWIND_DIR_CMD         20
+#define UFFS_API_GET_ERR_CMD            21
+#define UFFS_API_SET_ERR_CMD            22
+#define UFFS_API_FORMAT_CMD             23
+#define UFFS_API_SPACE_TOTAL_CMD        24
+#define UFFS_API_SPACE_FREE_CMD         25
+#define UFFS_API_SPACE_USED_CMD         26
+#define UFFS_API_FLUSH_ALL_CMD          27
+
+#define UFFS_API_CMD_LAST				27		// last test command id
+
+#define UFFS_API_CMD(header)            ((header)->cmd & 0xFF)
+#define UFFS_API_ACK_BIT                (1 << 31)
+
+#define UFFS_API_MAX_PARAMS             8
+
+struct uffs_ApiSrvMsgSt;
+
+struct uffs_ApiSrvHeaderSt {
+	u32 cmd;                // command
+	u32 data_len;           // data length
+	u32 n_params;           // parameter numbers
+	u32 param_size[UFFS_API_MAX_PARAMS];    // parameter list
+	u32 return_size[UFFS_API_MAX_PARAMS];	// return parameter list
+	u16 data_crc;           // data CRC16
+	u16 header_crc;         // header CRC16
+};
+
+struct uffs_ApiSrvIoSt {
+	int (*open)(void *addr);
+	int (*read)(int fd, void *buf, int len);
+	int (*write)(int fd, const void *buf, int len);
+	int (*close)(int fd);
+	void *addr;
+};
+
+struct uffs_ApiSt {
+	int (*uffs_version)(void);
+	int (*uffs_open)(const char *name, int oflag, ...);
+	int (*uffs_close)(int fd);
+	int (*uffs_read)(int fd, void *data, int len);
+	int (*uffs_write)(int fd, const void *data, int len);
+	int (*uffs_flush)(int fd);
+	long (*uffs_seek)(int fd, long offset, int origin);
+	long (*uffs_tell)(int fd);
+	int (*uffs_eof)(int fd);
+	int (*uffs_rename)(const char *old_name, const char *new_name);
+	int (*uffs_remove)(const char *name);
+	int (*uffs_ftruncate)(int fd, long remain);
+	int (*uffs_mkdir)(const char *name, ...);
+	int (*uffs_rmdir)(const char *name);
+	int (*uffs_stat)(const char *name, struct uffs_stat *buf);
+	int (*uffs_lstat)(const char *name, struct uffs_stat *buf);
+	int (*uffs_fstat)(int fd, struct uffs_stat *buf);
+	uffs_DIR * (*uffs_opendir)(const char *path);
+	int (*uffs_closedir)(uffs_DIR *dirp);
+	struct uffs_dirent * (*uffs_readdir)(uffs_DIR *dirp);
+	void (*uffs_rewinddir)(uffs_DIR *dirp);
+	int (*uffs_get_error)(void);
+	int (*uffs_set_error)(int err);
+	int (*uffs_format)(const char *mount_point);
+	long (*uffs_space_total)(const char *mount_point);
+	long (*uffs_space_used)(const char *mount_point);
+	long (*uffs_space_free)(const char *mount_point);
+	void (*uffs_flush_all)(const char *mount_point);
+};
+
+struct uffs_ApiSrvMsgSt {
+    struct uffs_ApiSrvHeaderSt header;
+    u8 *data;
+};
+
+int apisrv_setup_io(struct uffs_ApiSrvIoSt *io);
+int apisrv_serve(int fd, struct uffs_ApiSt *api);
+void apisrv_print_stat(void);
+struct uffs_ApiSt * apisrv_get_client(void);
+
+/* from api_test_server_{platform}.c */
+int api_server_start(void);
+
+/* from api_test_client_{platform}.c */
+int api_client_init(const char *server_addr);
+
+#endif
+

+ 125 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test_client_posix.c

@@ -0,0 +1,125 @@
+/*
+This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+UFFS is free software; you can redistribute it and/or modify it under
+the GNU Library General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+UFFS 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
+or GNU Library General Public License, as applicable, for more details.
+
+You should have received a copy of the GNU General Public License
+and GNU Library General Public License along with UFFS; if not, write
+to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA  02110-1301, USA.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered
+by the GNU General Public License. However the source code for this
+file must still be made available in accordance with section (3) of
+the GNU General Public License v2.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+
+/**
+* \file api_test_client_posix.c
+* \brief API test client functions
+* \author Ricky Zheng, created in 20 Dec, 2011
+*/
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <string.h>
+#include <errno.h>
+
+#include "uffs/uffs_fd.h"
+#include "api_test.h"
+
+
+static int _io_read(int fd, void *buf, int len)
+{
+    return recv(fd, buf, len, MSG_WAITALL);
+}
+
+static int _io_write(int fd, const void *buf, int len)
+{
+    return send(fd, buf, len, 0);
+}
+
+static int _io_open(void *addr)
+{
+    int sock;
+    struct hostent *host;
+    struct sockaddr_in server_addr;
+	int port = SRV_PORT;
+
+    host = gethostbyname((const char *)addr);
+
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+        perror("Socket");
+        return -1;
+    }
+
+	if (getenv("UFFS_TEST_SRV_PORT")) {
+		port = atoi(getenv("UFFS_TEST_SRV_PORT"));
+	}
+
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port = htons(port);
+    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
+    bzero(&(server_addr.sin_zero),8);
+
+    if (connect(sock, (struct sockaddr *)&server_addr,
+                sizeof(struct sockaddr)) == -1)
+    {
+        perror("Connect");
+        return -1;
+    }
+
+    return sock;
+}
+
+static int _io_close(int fd)
+{
+    return close(fd);
+}
+
+static struct uffs_ApiSrvIoSt m_io = {
+    .open = _io_open,
+    .read = _io_read,
+    .write = _io_write,
+    .close = _io_close,
+    .addr = (void *)"127.0.0.1",
+};
+
+int api_client_init(const char *server_addr)
+{
+	static char addr[128] = {0};
+	int ret = -1;
+	
+	if (server_addr == NULL)
+		server_addr = getenv("UFFS_TEST_SRV_ADDR");
+
+	if (server_addr && strlen(server_addr) < sizeof(addr)) {
+		strcpy(addr, server_addr);
+		m_io.addr = (void *)addr;
+	}
+	ret = apisrv_setup_io(&m_io);
+
+	return ret;
+}
+

+ 48 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test_client_win32.c

@@ -0,0 +1,48 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file api_test_client_win32.c
+ * \brief uffs API test client
+ * \author Ricky Zheng, 20 Dec 2011
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include "api_test.h"
+
+int api_client_init(const char *server_addr)
+{
+	printf("API test client not available on win32, stay tune ...\n");
+
+	return -1;
+}
+

+ 81 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test_client_wrapper.c

@@ -0,0 +1,81 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file api_test_client_wrapper.c
+ * \brief API test client wrapper
+ * \author Ricky Zheng, created at 20 Dec, 2011
+ */
+
+#include "uffs/uffs_fd.h"
+#include "api_test.h"
+
+#define W(R, F, T, P) \
+	R F T \
+	{ \
+		return apisrv_get_client()->F P ; \
+	}
+
+#define VW(F, T, P) \
+	void F T \
+	{ \
+		apisrv_get_client()->F P ; \
+	}
+
+W(int, uffs_version, (), ())
+W(int, uffs_open, (const char *name, int oflag, ...), (name, oflag))
+W(int, uffs_close, (int fd), (fd))
+W(int, uffs_read, (int fd, void *data, int len), (fd, data, len))
+W(int, uffs_write, (int fd, const void *data, int len), (fd, data, len))
+W(int, uffs_flush, (int fd), (fd))
+W(long, uffs_seek, (int fd, long offset, int origin), (fd, offset, origin))
+W(long, uffs_tell, (int fd), (fd))
+W(int, uffs_eof, (int fd), (fd))
+W(int, uffs_rename, (const char *oldname, const char *newname), (oldname, newname))
+W(int, uffs_remove, (const char *name), (name))
+W(int, uffs_ftruncate, (int fd, long remain), (fd, remain))
+W(int, uffs_mkdir, (const char *name, ...), (name))
+W(int, uffs_rmdir, (const char *name), (name))
+W(int, uffs_stat, (const char *name, struct uffs_stat *buf), (name, buf))
+W(int, uffs_lstat, (const char *name, struct uffs_stat *buf), (name, buf))
+W(int, uffs_fstat, (int fd, struct uffs_stat *buf), (fd, buf))
+W(uffs_DIR *, uffs_opendir, (const char *path), (path))
+W(int, uffs_closedir, (uffs_DIR *dirp), (dirp))
+W(struct uffs_dirent *, uffs_readdir, (uffs_DIR *dirp), (dirp))
+VW(uffs_rewinddir, (uffs_DIR *dirp), (dirp))
+W(int, uffs_get_error, (void), ())
+W(int, uffs_set_error, (int err), (err))
+W(int, uffs_format, (const char *mount), (mount))
+W(long, uffs_space_total, (const char *mount), (mount))
+W(long, uffs_space_used, (const char *mount), (mount))
+W(long, uffs_space_free, (const char *mount), (mount))
+VW(uffs_flush_all, (const char *mount), (mount))

+ 283 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test_server_posix.c

@@ -0,0 +1,283 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file api_test_server_posix.c
+ * \brief uffs API test server.
+ * \author Ricky Zheng
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "uffs/uffs_os.h"
+#include "uffs/uffs_public.h"
+#include "uffs/uffs_fs.h"
+#include "uffs/uffs_utils.h"
+#include "uffs/uffs_core.h"
+#include "uffs/uffs_mtb.h"
+#include "uffs/uffs_crc.h"
+#include "uffs/uffs_fd.h"
+#include "uffs/uffs_version.h"
+#include "api_test.h"
+
+#define PFX NULL
+
+#define BACKLOGS	100
+
+#define WORKER_THREAD_NUM	10	
+
+#define WORKER_FIFO_SIZE	30
+static pthread_mutex_t m_fifo_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t m_fifo_space_avail = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t m_fifo_fd_avail = PTHREAD_COND_INITIALIZER;
+static int m_fifo[WORKER_FIFO_SIZE];
+static int m_fifo_head = 0;
+static int m_fifo_tail = 0;
+
+static int m_thread_stat[WORKER_THREAD_NUM];
+
+static void push_fifo(int fd)
+{
+	pthread_mutex_lock(&m_fifo_lock);
+	if (((m_fifo_head + 1) % WORKER_FIFO_SIZE) != m_fifo_tail) {
+		m_fifo[m_fifo_head++] = fd;
+		m_fifo_head = m_fifo_head % WORKER_FIFO_SIZE;
+		pthread_cond_signal(&m_fifo_fd_avail);
+	}
+	else {
+		pthread_cond_wait(&m_fifo_space_avail, &m_fifo_lock);
+	}
+	pthread_mutex_unlock(&m_fifo_lock);
+}
+
+static int pop_fifo(void)
+{
+	int fd = -1;
+	pthread_mutex_lock(&m_fifo_lock);
+	if (m_fifo_head == m_fifo_tail) {
+		pthread_cond_wait(&m_fifo_fd_avail, &m_fifo_lock);
+	}
+	else {
+		fd = m_fifo[m_fifo_tail++];
+		m_fifo_tail = m_fifo_tail % WORKER_FIFO_SIZE;
+		pthread_cond_signal(&m_fifo_space_avail);
+	}
+	pthread_mutex_unlock(&m_fifo_lock);
+
+	return fd;
+}
+
+static int _io_read(int fd, void *buf, int len)
+{
+    return recv(fd, buf, len, MSG_WAITALL);
+}
+
+static int _io_write(int fd, const void *buf, int len)
+{
+    return send(fd, buf, len, 0);
+}
+
+static int _io_close(int fd)
+{
+    return close(fd);
+}
+
+static struct uffs_ApiSrvIoSt m_io = {
+    .read = _io_read,
+    .write = _io_write,
+    .close = _io_close,
+};
+
+static struct uffs_ApiSt m_api = {
+    uffs_version,
+    uffs_open,
+    uffs_close,
+    uffs_read,
+    uffs_write,
+    uffs_flush,
+    uffs_seek,
+    uffs_tell,
+    uffs_eof,
+    uffs_rename,
+    uffs_remove,
+    uffs_ftruncate,
+    uffs_mkdir,
+    uffs_rmdir,
+    uffs_stat,
+    uffs_lstat,
+    uffs_fstat,
+    uffs_opendir,
+    uffs_closedir,
+    uffs_readdir,
+    uffs_rewinddir,
+    uffs_get_error,
+    uffs_set_error,
+    uffs_format,
+    uffs_space_total,
+    uffs_space_used,
+    uffs_space_free,
+	uffs_flush_all,
+};
+
+static void * worker_thread_fn(void *param)
+{
+	int fd;
+	size_t id;
+	
+	id = (size_t)param;
+
+	while (1) {
+		fd = pop_fifo();
+		if (fd >= 0) {
+			apisrv_serve(fd, &m_api);
+			close(fd);
+			m_thread_stat[id]++;
+		}
+	}
+
+	return NULL;
+}
+
+static void create_worker_threads(void)
+{
+	static pthread_t worker_threads[WORKER_THREAD_NUM];
+	int i;
+
+	for (i = 0; i < WORKER_THREAD_NUM; i++) {
+		pthread_create(&worker_threads[i], NULL, worker_thread_fn, (void *)((size_t)i));
+	}
+}
+
+static void print_worker_thread_stat(void)
+{
+	int i;
+	printf("--- thread stat start ---\n");
+	for (i = 0; i < WORKER_THREAD_NUM; i++) {
+		printf("Thread %2d: %d\n", i, m_thread_stat[i]);
+	}
+	printf("--- thread stat end --\n");
+}
+
+static void *api_server_main_thread(void *param)
+{
+	int srv_fd = -1, new_fd = -1;
+	struct sockaddr_in my_addr;
+	struct sockaddr_in peer_addr;
+	socklen_t sin_size;
+	int yes = 1;
+	int ret = 0;
+	int port = SRV_PORT;
+
+	srv_fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (srv_fd < 0) {
+		perror("create srv socket error");
+		ret = -1;
+		goto ext;
+	}
+
+	if (getenv("UFFS_TEST_SRV_PORT")) {
+		port = atoi(getenv("UFFS_TEST_SRV_PORT"));
+	}
+
+	memset(&my_addr, 0, sizeof(struct sockaddr_in));
+	my_addr.sin_family = AF_INET; 			/* host byte order */
+	my_addr.sin_port = htons(port); 		/* short, network byte order */
+	my_addr.sin_addr.s_addr = INADDR_ANY;	/* 0.0.0.0 */
+
+	/* "Address already in use" error message */
+	ret = setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
+	if (ret < 0) {
+	  perror("setsockopt() error");
+	  goto ext;
+	}
+
+	ret = bind(srv_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
+	if (ret < 0) {
+	  perror("Server-bind() error");
+	  goto ext;
+	}
+
+	ret = listen(srv_fd, BACKLOGS);
+	if (ret < 0) {
+		perror("listen() error");
+		goto ext;
+	}
+
+	sin_size = sizeof(struct sockaddr_in);
+
+	apisrv_setup_io(&m_io);
+
+	create_worker_threads();
+
+	do {
+		new_fd = accept(srv_fd, (struct sockaddr *)&peer_addr, &sin_size);
+		if (new_fd >= 0) {
+			push_fifo(new_fd);
+		}
+	} while (ret >= 0);
+
+ext:
+	if (srv_fd >= 0)
+		close(srv_fd);
+
+	return param;
+}
+
+
+int api_server_start(void)
+{
+	static int started = 0;
+	pthread_t main_thread;
+	int ret = 0;
+
+	if (!started) {
+		started = 1;
+		ret = pthread_create(&main_thread, NULL, api_server_main_thread, NULL);
+	}
+	else {
+		apisrv_print_stat();
+		print_worker_thread_stat();
+		printf("apisrv already started.\n");
+	}
+
+	return ret;
+}
+
+

+ 194 - 0
components/dfs/filesystems/uffs/src/test/api_test/api_test_server_win32.c

@@ -0,0 +1,194 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file api_test_server_win32.c
+ * \brief uffs API test server.
+ * \author Ricky Zheng
+ */
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+
+#include "api_test.h"
+
+#pragma comment(lib, "Ws2_32.lib")
+
+#define BACKLOGS	10
+
+static int _io_read(int fd, void *buf, int len)
+{
+    return recv((SOCKET)fd, buf, len, 0);
+}
+
+static int _io_write(int fd, const void *buf, int len)
+{
+    return send((SOCKET)fd, buf, len, 0);
+}
+
+static int _io_close(int fd)
+{
+	closesocket((SOCKET)fd);
+
+    return 0;
+}
+
+static struct uffs_ApiSrvIoSt m_io = {
+	NULL,			// open
+    _io_read,
+    _io_write,
+    _io_close,
+};
+
+static struct uffs_ApiSt m_api = {
+    uffs_version,
+    uffs_open,
+    uffs_close,
+    uffs_read,
+    uffs_write,
+    uffs_flush,
+    uffs_seek,
+    uffs_tell,
+    uffs_eof,
+    uffs_rename,
+    uffs_remove,
+    uffs_ftruncate,
+    uffs_mkdir,
+    uffs_rmdir,
+    uffs_stat,
+    uffs_lstat,
+    uffs_fstat,
+    uffs_opendir,
+    uffs_closedir,
+    uffs_readdir,
+    uffs_rewinddir,
+    uffs_get_error,
+    uffs_set_error,
+    uffs_format,
+    uffs_space_total,
+    uffs_space_used,
+    uffs_space_free,
+	uffs_flush_all,
+};
+
+int api_server_start(void)
+{
+	int iResult;
+	int ret;
+	WSADATA wsaData;
+
+    SOCKET ListenSocket = INVALID_SOCKET;
+    SOCKET ClientSocket = INVALID_SOCKET;
+
+    struct addrinfo *result = NULL;
+    struct addrinfo hints;
+
+	char port_buf[16];
+
+	// Initialize Winsock
+	iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+	if (iResult != 0) {
+		printf("WSAStartup failed: %d\n", iResult);
+		return -1;
+	}
+
+	ZeroMemory( &hints, sizeof(hints) );
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+	hints.ai_flags = AI_PASSIVE;
+
+    // Resolve the server address and port
+	sprintf_s(port_buf, sizeof(port_buf), "%d", SRV_PORT);
+    iResult = getaddrinfo("0.0.0.0", port_buf, &hints, &result);
+    if ( iResult != 0 ) {
+        printf("getaddrinfo failed with error: %d\n", iResult);
+        ret = -1;
+        goto ext;
+    }
+
+    // Create a SOCKET for connecting to server
+    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
+    if (ListenSocket == INVALID_SOCKET) {
+        printf("socket failed with error: %ld\n", WSAGetLastError());
+        freeaddrinfo(result);
+        ret = -1;
+        goto ext;
+    }
+
+    // Setup the TCP listening socket
+    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
+    if (iResult == SOCKET_ERROR) {
+        printf("bind failed with error: %d\n", WSAGetLastError());
+        freeaddrinfo(result);
+        closesocket(ListenSocket);
+        ret = -1;
+        goto ext;
+    }
+
+    freeaddrinfo(result);
+
+    iResult = listen(ListenSocket, SOMAXCONN);
+    if (iResult == SOCKET_ERROR) {
+        printf("listen failed with error: %d\n", WSAGetLastError());
+        closesocket(ListenSocket);
+        ret = -1;
+        goto ext;
+    }
+
+	apisrv_setup_io(&m_io);
+
+	ret = -1;
+	do {
+		// Accept a client socket
+		ClientSocket = accept(ListenSocket, NULL, NULL);
+		if (ClientSocket == INVALID_SOCKET) {
+			printf("accept failed with error: %d\n", WSAGetLastError());
+			continue;
+		}
+		ret = apisrv_serve((int)ClientSocket, &m_api);
+		closesocket(ClientSocket);
+	} while (ret >= 0);
+
+ext:
+    WSACleanup();
+
+	return ret;
+}

+ 531 - 0
components/dfs/filesystems/uffs/src/test/api_test/os_uffs.c

@@ -0,0 +1,531 @@
+/*
+This file is part of UFFS, the Ultra-low-cost Flash File System.
+
+Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+UFFS is free software; you can redistribute it and/or modify it under
+the GNU Library General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+UFFS 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
+or GNU Library General Public License, as applicable, for more details.
+
+You should have received a copy of the GNU General Public License
+and GNU Library General Public License along with UFFS; if not, write
+to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA  02110-1301, USA.
+
+As a special exception, if other files instantiate templates or use
+macros or inline functions from this file, or you compile this file
+and link it with other works to produce a work based on this file,
+this file does not by itself cause the resulting work to be covered
+by the GNU General Public License. However the source code for this
+file must still be made available in accordance with section (3) of
+the GNU General Public License v2.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+
+/**
+* \file os_uffs.c
+* \brief This file is for interfacing UFFS to sqlite3 UNIX VFS, so that we
+*        can use sqlite3's test case to test out UFFS.
+* 
+* \author Ricky Zheng, created at 22 Dec, 2011 
+*/
+
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE 500
+
+#include "uffs/uffs_types.h"
+#include "uffs/uffs_fd.h"
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "api_test.h"
+
+
+#if 1
+#define DBG(args...) \
+	do { \
+		printf(args); \
+		fflush(stdout); \
+	} while(0)
+
+#else
+#define DBG(...) do{}while(0)
+#endif
+
+#define ASSERT(cond, fmt, ...) \
+	do { \
+		if (!(cond)) { \
+			printf("Assert (" #cond ") fail at %s:%s:%d: ", __FILE__, __FUNCTION__, __LINE__); \
+			printf(fmt, ## __VA_ARGS__); \
+			fflush(stdout); \
+			exit(1); \
+		} \
+	} while (0)
+
+#define MAX_OPEN_FDS 50
+struct fdmap_s {
+    int unix_fd;
+    int uffs_fd;
+	int bak_fd;
+	char name[256];
+    int valid;
+};
+static struct fdmap_s m_fdmap[MAX_OPEN_FDS];
+static struct fdmap_s m_fdmap_ext[MAX_OPEN_FDS];
+static pthread_mutex_t m_fdmap_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#define LOCK() pthread_mutex_lock(&m_fdmap_mutex)
+#define UNLOCK() pthread_mutex_unlock(&m_fdmap_mutex)
+
+static const char * get_uffs_name(const char *unix_name)
+{
+	const char *p = NULL;
+	if (unix_name) {
+		p = (char *)unix_name + strlen(unix_name) - 1;
+		for (; *p != '/' && p > unix_name; p--);
+	}
+
+	return p;
+}
+
+#define FOR_EACH_FD(s, map, p) \
+	for (p = &map[0], s = &map[MAX_OPEN_FDS]; p < s; p++) \
+		if (p->valid)
+
+
+static void open_check_fd(int unix_fd, int uffs_fd, const char *unix_name)
+{
+	int n = 0;
+	struct fdmap_s *s, *p;
+
+	LOCK();
+	FOR_EACH_FD(s, m_fdmap, p) {
+		if (p->unix_fd == unix_fd &&
+				strcmp(p->name, unix_name) == 0)
+			n++;
+	}
+	FOR_EACH_FD(s, m_fdmap_ext, p) {
+		if (p->unix_fd == unix_fd &&
+				strcmp(p->name, unix_name) == 0)
+			n++;
+	}
+	UNLOCK();
+	ASSERT(n == 1, "unix fd %d (name= %s) have %d entries\n", unix_fd, unix_name, n);
+
+	if (uffs_fd >= 0) {
+		n = 0;
+		LOCK();
+		FOR_EACH_FD(s, m_fdmap, p) {
+			if (p->uffs_fd == uffs_fd &&
+					strcmp(get_uffs_name(p->name), get_uffs_name(unix_name)) == 0)
+				n++;
+		}
+		UNLOCK();
+		ASSERT(n == 1, "uffs fd %d (name = %s) have %d entries\n", uffs_fd, get_uffs_name(unix_name), n);
+	}
+}
+
+static void unlink_check_fd(const char *unix_name)
+{
+	struct fdmap_s *s, *p;
+
+	LOCK();
+	FOR_EACH_FD(s, m_fdmap, p) {
+		if (strcmp(p->name, unix_name) == 0) {
+			// there file already open ? close it ...
+			DBG("WARNING: unlink %s, but file is not closed ?\n", unix_name);
+		}
+	}
+	FOR_EACH_FD(s, m_fdmap_ext, p) {
+		if (strcmp(p->name, unix_name) == 0) {
+			DBG("WARNING: unlink %s, but file is not closed ?\n", unix_name);
+		}
+	}
+	UNLOCK();
+
+}
+
+// return 0 if not in skip table, else return non-zero. 
+static int check_skip_tbl(const char *path)
+{
+	static const char *skip_tbl[] = {
+		"/dev/", "/var/", "/tmp/", "/proc/", "/usr/", "/lib/", "/opt/", "/bin/", NULL /* end */
+	};
+	int i = 0;
+
+	for (i = 0; skip_tbl[i] != NULL; i++) {
+		if (memcmp(path, skip_tbl[i], strlen(skip_tbl[i])) == 0)
+			return 1;
+	}
+
+	return 0;	
+}
+
+static int unix2uffs(int unix_fd, int *uffs_fd, int *bak_fd)
+{
+    int ret = -1;
+    struct fdmap_s *s, *p;
+
+    LOCK();
+	FOR_EACH_FD(s, m_fdmap, p) {
+        if (p->unix_fd == unix_fd) {
+			if (*uffs_fd)
+				*uffs_fd = p->uffs_fd;
+			if (bak_fd)
+				*bak_fd = p->bak_fd;
+			ret = 0;
+            break;
+        }
+    }
+    UNLOCK();
+
+    return ret;
+}
+
+static int push_newfd(const char *unix_name, int unix_fd, int uffs_fd, int bak_fd)
+{
+    int ret = -1;
+    struct fdmap_s *p, *end;
+
+    if (unix_fd < 0)
+        return -1;
+
+    if (uffs_fd >= 0) {
+        p = &m_fdmap[0];
+        end = &m_fdmap[MAX_OPEN_FDS];
+    }
+    else {
+        p = &m_fdmap_ext[0];
+        end = &m_fdmap_ext[MAX_OPEN_FDS];
+    }
+
+    LOCK();
+    while (p < end) {
+        if (!p->valid) {
+            p->unix_fd = unix_fd;
+            p->uffs_fd = uffs_fd;
+			p->bak_fd = bak_fd;
+			strcpy(p->name, unix_name);
+            p->valid = 1;
+            ret = 0;
+			DBG("push_newfd(unix_fd = %d, uffs_fd = %d, bak_fd = %d)\n", unix_fd, uffs_fd, bak_fd);
+            break;
+        }
+        p++;
+    }
+    UNLOCK();
+
+    return ret;
+}
+
+static int remove_fd(int unix_fd)
+{
+    int ret = -1;
+    struct fdmap_s *s, *p;
+
+
+    LOCK();
+	FOR_EACH_FD(s, m_fdmap, p) {
+        if (p->unix_fd == unix_fd) {
+            p->valid = 0;
+            ret = 0;
+			DBG("remove_fd(unix_fd = %d), uffs_fd = %d, bak_fd = %d\n", unix_fd, p->uffs_fd, p->bak_fd);
+            break;
+        }
+    }
+
+    if (ret != 0) {
+		FOR_EACH_FD(s, m_fdmap_ext, p) {
+            if (p->unix_fd == unix_fd) {
+                p->valid = 0;
+                ret = 0;
+				DBG("remove_fd(unix_fd = %d), no uffs_fd\n", unix_fd);
+                break;
+            }
+        }
+    }
+
+    UNLOCK();
+
+    return ret;
+}
+
+int os_open(const char *name, int flags, int mode)
+{
+    int fd = -1;
+    int uffs_fd = -1, uffs_flags = 0;
+	int bak_fd = -1;
+	const char *p;
+	char bak_name[256] = {0};
+
+    fd = open(name, flags, mode);
+
+    if (check_skip_tbl(name) == 0 && fd >= 0) {
+        uffs_flags = 0;
+        if (flags & O_WRONLY) uffs_flags |= UO_WRONLY;
+        if (flags & O_RDWR) uffs_flags |= UO_RDWR;
+        if (flags & O_CREAT) uffs_flags |= UO_CREATE;
+        if (flags & O_TRUNC) uffs_flags |= UO_TRUNC;
+        if (flags & O_EXCL) uffs_flags |= UO_EXCL;
+		
+		p = get_uffs_name(name);
+		uffs_fd = uffs_open(p, uffs_flags);
+		if (uffs_fd >= 0) {
+			sprintf(bak_name, "bak%s", p);
+			bak_fd = open(bak_name, flags, mode);
+		}
+
+		// sqlite3 testing script might delete test.db file outside the control of sqlite lib, 
+		// so we need to detect that situation.
+		if ( /* strcmp(p, "/test.db") == 0 && */ uffs_fd >= 0 && (flags & O_CREAT)) {
+			ASSERT(bak_fd >= 0, "bak name = %s, bak fd = %d\n", bak_name, bak_fd); 
+			struct stat sbuf;
+			if (fstat(fd, &sbuf) == 0 && sbuf.st_size == 0) {
+				// "test.db" file just been created, we should also do that on UFFS as well
+				uffs_ftruncate(uffs_fd, 0);
+				ftruncate(bak_fd, 0);
+			}
+		}
+    }
+
+	if (fd > 0) {
+	    ASSERT(!push_newfd(name, fd, uffs_fd, bak_fd), "push_newfd(fd=%d, uffs_fd=%d, bak_fd=%d)\n", fd, uffs_fd, bak_fd);
+		open_check_fd(fd, uffs_fd, name);
+	}
+
+	DBG("open(name = \"%s\", flags = 0x%x, mode = 0x%x) = %d %s\n", name, flags, mode, fd, uffs_fd >= 0 ? "U" : "");
+
+    return fd;
+}
+
+int os_unlink(const char *name)
+{
+	int ret = -1, uffs_ret = -1, bak_ret = -1;
+	const char *p = NULL;
+	char bak_name[256];
+
+	if (name) {
+		unlink_check_fd(name);
+		ret = unlink(name);
+		if (check_skip_tbl(name) == 0) {
+			p = get_uffs_name(name);
+			uffs_ret = uffs_remove(p);
+			sprintf(bak_name, "bak%s", p);
+			bak_ret = unlink(bak_name);
+			ASSERT(uffs_ret == ret && ret == bak_ret, "unlink(\"%s\"), unix return %d, uffs return %d, bak return %d\n", name, ret, uffs_ret, bak_ret);
+		}
+	}
+	DBG("unlink(name = \"%s\") = %d %s\n", name, ret, p ? "U" : "");
+
+	return ret;
+}
+
+int os_close(int fd)
+{
+    int uffs_fd = -1, bak_fd = -1;
+    int ret = -1;
+	int x = -1;
+
+    if (fd >= 0) {
+        unix2uffs(fd, &uffs_fd, &bak_fd);
+        if (uffs_fd >= 0) {
+            uffs_close(uffs_fd);
+        }
+		if (bak_fd >= 0)
+			close(bak_fd);
+
+		x = remove_fd(fd);
+        //ASSERT(!x, "remove_fd(%d) failed.\n", fd);
+        ret = close(fd);
+    }
+
+	DBG("close(fd = %d) = %d  %s\n", fd, ret, uffs_fd >= 0 ? "U" : "");
+
+    return ret;
+}
+
+int os_read(int fd, void *buf, int len)
+{
+	int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
+	int ret = -1;
+	void *uffs_buf = NULL;
+	void *bak_buf = NULL;
+	int i;
+	unsigned char a,b,c;
+
+	if (fd >= 0) {
+		unix2uffs(fd, &uffs_fd, &bak_fd);
+		if (uffs_fd >= 0) {
+			uffs_buf = malloc(len);
+			bak_buf = malloc(len);
+			ASSERT(uffs_buf != NULL || bak_buf == NULL, "malloc(%d) failed.\n", len);
+			uffs_ret = uffs_read(uffs_fd, uffs_buf, len);
+			bak_ret = read(bak_fd, bak_buf, len);
+		}
+		ret = read(fd, buf, len);
+		if (uffs_fd >= 0) {
+			ASSERT(ret == uffs_ret && uffs_ret == bak_ret, "read(fd=%d/%d/%d,buf,len=%d), unix return %d, uffs return %d, bak return %d\n", fd, uffs_fd, bak_fd, len, ret, uffs_ret, bak_ret);
+			//assert(memcmp(buf, uffs_buf, len) == 0);	
+			if (ret > 0) {
+				if (memcmp(buf, uffs_buf, ret) != 0) {
+					DBG("ERR: read result different! from fd = %d/%d, len = %d, ret = %d\n", fd, uffs_fd, len, ret);
+						printf("\t  POS  unix  uffs  bak\n");	
+					for (i = 0; i < len; i++) {
+						a = *(((char *)buf) + i);
+						b = *(((char *)uffs_buf) + i);
+						c = *(((char *)bak_buf) + i);
+						printf("\t0x%08d: 0x%02x 0x%02x 0x%02x%s\n", i, a, b, c, a == b && b == c ? "" : "  <----");
+					}
+					fflush(stdout);
+					assert(0);
+				}
+			}
+		}
+	}
+
+	if (uffs_buf)
+		free(uffs_buf);
+
+	if (bak_buf)
+		free(bak_buf);
+
+	DBG("read(fd = %d, buf = {...}, len = %d) = %d %s\n", fd, len, ret, uffs_fd >= 0 ? "U" : "");
+
+	return ret;
+}
+
+int os_write(int fd, const void *buf, int len)
+{
+	int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
+	int ret = -1;
+
+	if (fd >= 0) {
+		unix2uffs(fd, &uffs_fd, &bak_fd);
+		if (uffs_fd >= 0) {
+			uffs_ret = uffs_write(uffs_fd, buf, len);
+			ASSERT(bak_fd >= 0, "uffs_fd = %d, bak_fd = %d\n", uffs_fd, bak_fd);
+			bak_ret = write(bak_fd, buf, len);
+		}
+		ret = write(fd, buf, len);
+		if (uffs_fd >= 0) {
+			ASSERT(ret == uffs_ret && ret == bak_ret, "write(fd=%d/%d/%d,buf,len=%d), unix return %d, uffs return %d, bak return %d\n", fd, uffs_fd, bak_fd, len, ret, uffs_ret, bak_ret);
+		}
+	}
+
+	DBG("write(fd = %d, buf = {...}, len = %d) = %d  %s\n", fd, len, ret, uffs_fd >= 0 ? "U" : "");
+
+	return ret;
+}
+
+int os_lseek(int fd, long offset, int origin)
+{
+	long ret = -1;
+	int uffs_fd = -1, bak_fd = -1;
+	long uffs_ret = -1L, bak_ret = -1L;
+	int uffs_origin = 0;
+
+	if (fd >= 0) {
+		unix2uffs(fd, &uffs_fd, &bak_fd);
+		if (uffs_fd >= 0) {
+			if (origin == SEEK_CUR)
+				uffs_origin = USEEK_CUR;
+			else if (origin == SEEK_SET)
+				uffs_origin = USEEK_SET;
+			else if (origin == SEEK_END)
+				uffs_origin = USEEK_END;
+
+			uffs_ret = uffs_seek(uffs_fd, offset, uffs_origin);
+			bak_ret = lseek(bak_fd, offset, origin);
+		}
+
+		ret = lseek(fd, offset, origin);
+
+		if (uffs_fd >= 0) {
+			ASSERT(ret == uffs_ret && ret == bak_ret, "lseek(fd=%d/%d/%d, offset=%ld, origin=%d), unix return %ld, uffs return %ld, bak return %ld\n", fd, uffs_fd, bak_fd, offset, origin, ret, uffs_ret, bak_ret);
+		}
+	}
+
+	DBG("lseek(fd = %d, offset = %ld, origin = %d) = %ld  %s\n", fd, offset, origin, ret, uffs_fd >= 0 ? "U" : "");
+
+	return ret;
+}
+
+int os_pread(int fd, void *buf, int count, long offset)
+{
+	DBG("pread(fd = %d, buf = {...}, count = %d, offset = %ld)\n", fd, count, offset);
+	assert(0);
+	return pread(fd, buf, count, offset);
+}
+
+int os_pwrite(int fd, const void *buf, int count, long offset)
+{
+	DBG("pwrite(fd = %d, buf = {..}, count = %d, offset = %ld)\n", fd, count, offset);
+	assert(0);
+	return pwrite(fd, buf, count, offset);
+}
+
+int os_ftruncate(int fd, long length)
+{
+	int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
+	int ret = -1;
+
+	if (fd >= 0) {
+		unix2uffs(fd, &uffs_fd, &bak_fd);
+		ret = ftruncate(fd, length);
+		if (uffs_fd >= 0) {
+			uffs_ret = uffs_ftruncate(uffs_fd, length);
+			bak_ret = ftruncate(bak_fd, length);
+			ASSERT(ret == uffs_ret && ret == bak_ret,
+					"ftruncate(fd=%d/%d/%d, length=%ld), unix ret %d, uffs ret %d, bak ret %d\n",
+					fd, uffs_fd, bak_fd, length, ret, uffs_ret, bak_ret);
+		}
+	}
+	DBG("ftruncate(fd = %d, length = %ld) = %d %s\n", fd, length, ret, uffs_fd >= 0 ? "U" : "");
+
+	return ret;
+}
+
+int os_posix_fallocate(int fd, long offset, long len)
+{
+	assert(0);
+	DBG("posix_fallocate(fd = %d, offset = %ld, len = %ld)\n", fd, offset, len);
+	return posix_fallocate(fd, offset, len);
+}
+
+int os_uffs_init(void)
+{
+	static int inited = 0;
+	const char *apisrv_addr;
+
+	if (!inited) {
+		inited = 1;
+		memset(m_fdmap, 0, sizeof(m_fdmap));
+		memset(m_fdmap_ext, 0, sizeof(m_fdmap_ext));
+
+		mkdir("bak", 0777);	// for mirroring UFFS 
+
+		apisrv_addr = getenv("UFFS_TEST_SRV_ADDR");
+		if (apisrv_addr == NULL)
+			apisrv_addr = "127.0.0.1";
+
+		DBG("os_uffs_init() called, server addr: %s\n", apisrv_addr);
+	
+		return api_client_init(apisrv_addr);
+	}
+	else
+		return 0;
+}

+ 46 - 0
components/dfs/filesystems/uffs/src/test/api_test/os_uffs.h

@@ -0,0 +1,46 @@
+/*
+  This file is part of UFFS, the Ultra-low-cost Flash File System.
+  
+  Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
+
+  UFFS is free software; you can redistribute it and/or modify it under
+  the GNU Library General Public License as published by the Free Software 
+  Foundation; either version 2 of the License, or (at your option) any
+  later version.
+
+  UFFS 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
+  or GNU Library General Public License, as applicable, for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  and GNU Library General Public License along with UFFS; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  Boston, MA  02110-1301, USA.
+
+  As a special exception, if other files instantiate templates or use
+  macros or inline functions from this file, or you compile this file
+  and link it with other works to produce a work based on this file,
+  this file does not by itself cause the resulting work to be covered
+  by the GNU General Public License. However the source code for this
+  file must still be made available in accordance with section (3) of
+  the GNU General Public License v2.
+ 
+  This exception does not invalidate any other reasons why a work based
+  on this file might be covered by the GNU General Public License.
+*/
+
+/**
+ * \file os_uffs.h
+ * \brief header file for interfacing to sqlite3 
+ * \author Ricky Zheng, created at 22 Dec, 2011
+ */
+
+#ifndef _OS_UFFS_
+#define _OS_UFFS_
+
+int os_open(const char *name, int oflags, int mode);
+int os_close(int fd);
+
+#endif
+

+ 14 - 0
components/dfs/filesystems/uffs/src/test/clients/CMakeLists.txt

@@ -0,0 +1,14 @@
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
+INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/test/api_test)
+
+IF (UNIX)
+	SET(example_SRCS example.c)
+	SET(example2_SRCS example-2.c)
+	ADD_EXECUTABLE(example ${example_SRCS})
+	ADD_EXECUTABLE(example-2 ${example2_SRCS})
+	TARGET_LINK_LIBRARIES(example apitest_client)
+	TARGET_LINK_LIBRARIES(example-2 apitest_client)
+ENDIF()
+
+

+ 35 - 0
components/dfs/filesystems/uffs/src/test/clients/example-2.c

@@ -0,0 +1,35 @@
+/*
+ * This is a APT test client example
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "uffs/uffs_fd.h"
+#include "api_test.h"
+
+
+int main(int argc, char *argv[])
+{
+	int interval = 1000;
+
+	if (argc > 2) {
+		interval = atoi(argv[2]);
+	}
+
+	printf("Host: %s, Interval: %d\n", argv[1], interval);
+
+	if (api_client_init(argv[1]) == 0) {
+		while(1) {
+			uffs_flush_all("/");
+			usleep(interval * 1000);
+		}
+	}
+	else {
+		printf("init failed.\n");
+	}
+
+	return 0;
+}
+

+ 58 - 0
components/dfs/filesystems/uffs/src/test/clients/example.c

@@ -0,0 +1,58 @@
+/*
+ * This is a APT test client example
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "uffs/uffs_fd.h"
+#include "api_test.h"
+
+
+int main(int argc, char *argv[])
+{
+	int version;
+	int fd;
+	char buf[128];
+
+	api_client_init("192.168.0.103");
+
+	version = uffs_version();
+	printf("Version: %08X\n", version);
+
+	fd = uffs_open("/test.txt", UO_RDWR|UO_CREATE);
+	if (fd < 0) {
+		printf("Can't create /test.txt\n");
+		return -1;
+	}
+	
+	sprintf(buf, "Hello, this is test\n");
+	if (uffs_write(fd, buf, strlen(buf)) < 0) {
+		printf("call uffs_write failed\n");
+	}
+	else {
+		if (uffs_seek(fd, 7, USEEK_SET) != 7) {
+			printf("call uffs_seek failed\n");
+		}
+		else {
+			if (uffs_read(fd, buf, 4) != 4) {
+				printf("call uffs_read failed\n");
+			}
+			else {
+				if (memcmp(buf, "this", 4) != 0) {
+					printf("uffs_read content not matched\n");
+				}
+				else {
+					printf("everything is ok.\n");
+				}
+			}
+		}
+	}
+
+	if (uffs_close(fd) < 0) {
+		printf("uffs_close failed.\n");
+	}
+
+	return 0;
+}
+

+ 22 - 0
components/dfs/filesystems/uffs/src/test/scripts/_t1_sub1.ts

@@ -0,0 +1,22 @@
+# $9 --- fd
+# $8 --- counter, file content
+
+evl $8 % 60
+set 6 $1
+evl $1 * 508
+set 7 $1
+
+echo --- testing n = $8 / $6, offset = $7 ---
+
+t_seek $9 $7 s
+! abort --- seek file failed ---
+t_write $9 $8
+! abort --- write file (n=$8) failed ---
+t_seek $9 $7 s
+! abort --- seek file failed ---
+t_read $9 $8
+! abort --- read file compare failed n=$8 ---
+
+evl $8 + 1
+set 8 $1
+

+ 21 - 0
components/dfs/filesystems/uffs/src/test/scripts/test1.ts

@@ -0,0 +1,21 @@
+#rm /a
+# * 10 t3 /a
+t_open w /a
+set 9 $1
+
+echo --- test batch 1 ---
+set 8 0
+* 10 script _t1_sub1.ts
+
+echo --- test batch 2 ---
+set 8 32
+* 10 script _t1_sub1.ts
+
+echo --- test batch 3 ---
+set 8 70
+* 10 script _t1_sub1.ts
+
+t_close $9
+
+
+

+ 67 - 0
components/dfs/filesystems/uffs/src/test/scripts/test2.ts

@@ -0,0 +1,67 @@
+t_open cw /a
+! abort --- create file /a failed.
+set 9 $1
+
+t_write_seq $9 1000
+! abort
+t_write_seq $9 100
+! abort
+t_write_seq $9 10
+! abort
+t_write_seq $9 1
+! abort
+t_seek $9 100
+! abort
+t_write_seq $9 1000
+! abort
+t_write_seq $9 100
+! abort
+t_write_seq $9 10
+! abort
+t_write_seq $9 1
+! abort
+t_seek $9 500
+! abort
+t_write_seq $9 1000
+! abort
+t_write_seq $9 100
+! abort
+t_write_seq $9 10
+! abort
+t_write_seq $9 1
+! abort
+t_seek $9 1500
+! abort
+t_write_seq $9 1000
+! abort
+t_write_seq $9 100
+! abort
+t_write_seq $9 10
+! abort
+t_write_seq $9 1
+! abort
+
+# check ...
+t_seek $9 0
+! abort
+t_check_seq $9 1000
+! abort
+t_seek $9 1
+! abort
+t_check_seq $9 1000
+! abort
+t_seek $9 1000
+! abort
+t_check_seq $9 10
+! abort
+t_seek $9 100
+! abort
+t_check_seq $9 500
+! abort
+t_seek $9 2000
+! abort
+t_check_seq $9 100
+! abort
+
+t_close $9
+echo -- test succ --

+ 70 - 0
components/dfs/filesystems/uffs/src/test/scripts/test_delete.ts

@@ -0,0 +1,70 @@
+#
+# test delete file/dir
+#
+rm /a
+
+#####################################
+echo == test normal delete ==
+#####################################
+
+t_open cw /a
+! abort --- Can't create file /a ---
+set 9 $1
+t_write_seq $9 100
+! abort --- write file failed ---
+t_close $9
+! abort --- close file failed ---
+rm /a
+! abort --- can't delete /a ---
+
+
+###############################################
+echo == test not delete if a file is opened ==
+###############################################
+
+t_open cw /a
+! abort --- Can't create file /a ---
+set 9 $1
+t_write_seq $9 100
+! abort --- write file failed ---
+rm /a
+# this should failed, save $?(-1) to $8.
+set 8 $?
+t_close $9
+! abort --- fail to close file ---
+test $8 == -1
+! abort --- can delete a file in use ? ---
+
+######################################
+echo == test delete empty dir ==
+######################################
+
+rm /xx
+mkdir /xx
+! abort -- can't create /xx --
+mkdir /xx/yy
+! abort -- can't create /xx/yy --
+rm /xx/yy
+! abort -- can't delete /xx/yy ---
+rm /xx
+! abort -- can't delet /xx
+
+#########################################
+echo == test not delete non-empty dir ==
+#########################################
+
+mkdir /xx
+t1 /xx/a.txt
+rm /xx
+test $? == -1
+! abort --- delete a non-empty dir success ?? ---
+rm /xx/a.txt
+! abort --- can't delete /xx/a.txt ---
+rm /xx
+! abort --- can't delet /xx ---
+
+
+echo ##################################
+echo -------- ALL TEST SUCCESS --------
+echo ##################################
+

+ 60 - 0
components/dfs/filesystems/uffs/src/test/scripts/test_seek.ts

@@ -0,0 +1,60 @@
+rm /test_seek.bin
+
+# create a new file
+t_open wc /test_seek.bin
+
+! abort ---- create file failed ----
+set 9 $1  # opened fd => $9
+
+# test seek and write
+t_write $9 hello-world
+! abort ---- write file failed ----
+t_seek $9 5 s
+! abort --- seek file to 5 failed ---
+test $1 == 5
+! abort --- file pointer is not 5 ---
+t_write $9 &
+! abort --- write '&' at position 5 failed ---
+t_seek $9 0 s
+! abort --- seek file to 0 failed
+test $1 == 0
+! abort -- file pointer not 0 ---
+t_read $9 hello&world
+! abort --- check file failed ---
+
+# test seek in different options
+t_seek $9 0 s
+test $1 == 0
+! abort -- file pointer seek to 0 s failed --
+t_seek $9 100 s
+test $1 == 100
+! abort -- file pointer seek to 100 s failed --
+t_seek $9 10 c
+test $1 == 110
+! abort -- file pointer seek to +10 c failed --
+t_seek $9 -10 c
+test $1 == 100
+! abort -- file pointer seek to -10 c failed --
+t_seek $9 0 e
+test $1 == 11
+! abort -- file pointer seek to 0 e failed --
+t_seek $9 -1 e
+test $1 == 10
+! abort -- file pointer seek to -1 e failed --
+t_seek $9 10 e
+test $1 == 21
+! abort -- file pointer seek to +10 e failed --
+
+# now the file pointer is passed over the end of file,
+# write to it will increase file size and filling 0 in the gap
+
+t_write $9 a
+test $? == 0
+! abort -- file write to position passed over file length failed --
+t_seek $9 0 e
+test $1 == 22
+! abort -- file new length not filling the gap --
+
+t_close $9
+! abort --- close file failed ---
+echo === test seek success ===

+ 963 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile

@@ -0,0 +1,963 @@
+#!/usr/make
+#
+# Makefile for SQLITE
+#
+# This makefile is suppose to be configured automatically using the
+# autoconf.  But if that does not work for you, you can configure
+# the makefile manually.  Just set the parameters below to values that
+# work well for your system.
+#
+# If the configure script does not work out-of-the-box, you might
+# be able to get it to work by giving it some hints.  See the comment
+# at the beginning of configure.in for additional information.
+#
+
+# The toplevel directory of the source tree.  This is the directory
+# that contains this "Makefile.in" and the "configure.in" script.
+#
+TOP = .
+
+# C Compiler and options for use in building executables that
+# will run on the platform that is doing the build.
+#
+BCC = gcc  -g -O2
+
+# C Compile and options for use in building executables that 
+# will run on the target platform.  (BCC and TCC are usually the
+# same unless your are cross-compiling.)
+#
+TCC = gcc   -g -O2 -DSQLITE_OS_UNIX=1 -I. -I${TOP}/src -I${TOP}/ext/rtree
+
+# Define this for the autoconf-based build, so that the code knows it can
+# include the generated config.h
+# 
+TCC += -D_HAVE_SQLITE_CONFIG_H
+
+# Define -DNDEBUG to compile without debugging (i.e., for production usage)
+# Omitting the define will cause extra debugging code to be inserted and
+# includes extra comments when "EXPLAIN stmt" is used.
+#
+TCC += -DNDEBUG 
+
+# test UFFS
+TCC += -DUFFS_TEST
+
+UFFS_BUILD_PATH = $(HOME)/build/uffs
+
+# Compiler options needed for programs that use the TCL library.
+#
+TCC += -I/usr/include/tcl8.5
+
+# The library that programs using TCL must link against.
+#
+LIBTCL = -L/usr/lib -ltcl8.5 -ldl  -lpthread -lieee -lm
+
+# Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
+
+# The library that programs using readline() must link against.
+#
+LIBREADLINE = -lreadline -lreadline 
+
+# Should the database engine be compiled threadsafe
+#
+TCC += -DSQLITE_THREADSAFE=1
+
+# Any target libraries which libsqlite must be linked against
+# 
+TLIBS = -lpthread -L$(UFFS_BUILD_PATH)/src/test/api_test -lapitest_sqlite3
+
+
+# Flags controlling use of the in memory btree implementation
+#
+# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
+# default to file, 2 to default to memory, and 3 to force temporary
+# tables to always be in memory.
+#
+TEMP_STORE = -DSQLITE_TEMP_STORE=1
+
+# Enable/disable loadable extensions, and other optional features
+# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).  
+# The same set of OMIT and ENABLE flags should be passed to the 
+# LEMON parser generator and the mkkeywordhash tool as well.
+OPT_FEATURE_FLAGS = -DSQLITE_OMIT_LOAD_EXTENSION=1
+
+TCC += $(OPT_FEATURE_FLAGS)
+
+# Add in any optional parameters specified on the make commane line
+# ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
+TCC += $(OPTS)
+
+# Version numbers and release number for the SQLite being compiled.
+#
+VERSION = 3.7
+VERSION_NUMBER = 3007009
+RELEASE = 3.7.9
+
+# Filename extensions
+#
+BEXE = 
+TEXE = 
+
+# The following variable is "1" if the configure script was able to locate
+# the tclConfig.sh file.  It is an empty string otherwise.  When this
+# variable is "1", the TCL extension library (libtclsqlite3.so) is built
+# and installed.
+#
+HAVE_TCL = 1
+
+# This is the command to use for tclsh - normally just "tclsh", but we may
+# know the specific version we want to use
+#
+TCLSH_CMD = tclsh8.5
+
+# Where do we want to install the tcl plugin
+#
+TCLLIBDIR = /usr/share/tcltk/tcl8.5/sqlite3
+
+# The suffix used on shared libraries.  Ex:  ".dll", ".so", ".dylib"
+#
+SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+
+# If gcov support was enabled by the configure script, add the appropriate
+# flags here.  It's not always as easy as just having the user add the right
+# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
+# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.  
+# Supposedly GCC does the right thing if you use --coverage, but in 
+# practice it still fails.  See:
+#
+# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html
+#
+# for more info.
+#
+GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage
+GCOV_LDFLAGS1 = -lgcov
+USE_GCOV = 0
+LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
+LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
+
+
+# The directory into which to store package information for
+
+# Some standard variables and programs
+#
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+pkgconfigdir = $(libdir)/pkgconfig
+bindir = ${exec_prefix}/bin
+includedir = ${prefix}/include
+INSTALL = /usr/bin/install -c
+LIBTOOL = ./libtool
+ALLOWRELEASE = 
+
+# libtool compile/link/install
+LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
+LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS)  $(LTLINK_EXTRAS)
+LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
+
+# nawk compatible awk.
+NAWK = gawk
+
+# You should not have to change anything below this line
+###############################################################################
+
+USE_AMALGAMATION = 1
+
+# Object files for the SQLite library (non-amalgamation).
+#
+LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
+         backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
+         callback.lo complete.lo ctime.lo date.lo delete.lo \
+         expr.lo fault.lo fkey.lo \
+         fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \
+         fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \
+         func.lo global.lo hash.lo \
+         icu.lo insert.lo journal.lo legacy.lo loadext.lo \
+         main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
+         memjournal.lo \
+         mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
+         notify.lo opcodes.lo os.lo os_os2.lo os_unix.lo os_win.lo \
+         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
+         random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
+         table.lo tokenize.lo trigger.lo \
+         update.lo util.lo vacuum.lo \
+         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
+         vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
+
+# Object files for the amalgamation.
+#
+LIBOBJS1 = sqlite3.lo
+
+# Determine the real value of LIBOBJ based on the 'configure' script
+#
+LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION))
+
+
+# All of the source code files.
+#
+SRC = \
+  $(TOP)/src/alter.c \
+  $(TOP)/src/analyze.c \
+  $(TOP)/src/attach.c \
+  $(TOP)/src/auth.c \
+  $(TOP)/src/backup.c \
+  $(TOP)/src/bitvec.c \
+  $(TOP)/src/btmutex.c \
+  $(TOP)/src/btree.c \
+  $(TOP)/src/btree.h \
+  $(TOP)/src/btreeInt.h \
+  $(TOP)/src/build.c \
+  $(TOP)/src/callback.c \
+  $(TOP)/src/complete.c \
+  $(TOP)/src/ctime.c \
+  $(TOP)/src/date.c \
+  $(TOP)/src/delete.c \
+  $(TOP)/src/expr.c \
+  $(TOP)/src/fault.c \
+  $(TOP)/src/fkey.c \
+  $(TOP)/src/func.c \
+  $(TOP)/src/global.c \
+  $(TOP)/src/hash.c \
+  $(TOP)/src/hash.h \
+  $(TOP)/src/hwtime.h \
+  $(TOP)/src/insert.c \
+  $(TOP)/src/journal.c \
+  $(TOP)/src/legacy.c \
+  $(TOP)/src/loadext.c \
+  $(TOP)/src/main.c \
+  $(TOP)/src/malloc.c \
+  $(TOP)/src/mem0.c \
+  $(TOP)/src/mem1.c \
+  $(TOP)/src/mem2.c \
+  $(TOP)/src/mem3.c \
+  $(TOP)/src/mem5.c \
+  $(TOP)/src/memjournal.c \
+  $(TOP)/src/mutex.c \
+  $(TOP)/src/mutex.h \
+  $(TOP)/src/mutex_noop.c \
+  $(TOP)/src/mutex_os2.c \
+  $(TOP)/src/mutex_unix.c \
+  $(TOP)/src/mutex_w32.c \
+  $(TOP)/src/notify.c \
+  $(TOP)/src/os.c \
+  $(TOP)/src/os.h \
+  $(TOP)/src/os_common.h \
+  $(TOP)/src/os_os2.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
+  $(TOP)/src/pager.c \
+  $(TOP)/src/pager.h \
+  $(TOP)/src/parse.y \
+  $(TOP)/src/pcache.c \
+  $(TOP)/src/pcache.h \
+  $(TOP)/src/pcache1.c \
+  $(TOP)/src/pragma.c \
+  $(TOP)/src/prepare.c \
+  $(TOP)/src/printf.c \
+  $(TOP)/src/random.c \
+  $(TOP)/src/resolve.c \
+  $(TOP)/src/rowset.c \
+  $(TOP)/src/select.c \
+  $(TOP)/src/status.c \
+  $(TOP)/src/shell.c \
+  $(TOP)/src/sqlite.h.in \
+  $(TOP)/src/sqlite3ext.h \
+  $(TOP)/src/sqliteInt.h \
+  $(TOP)/src/sqliteLimit.h \
+  $(TOP)/src/table.c \
+  $(TOP)/src/tclsqlite.c \
+  $(TOP)/src/tokenize.c \
+  $(TOP)/src/trigger.c \
+  $(TOP)/src/utf.c \
+  $(TOP)/src/update.c \
+  $(TOP)/src/util.c \
+  $(TOP)/src/vacuum.c \
+  $(TOP)/src/vdbe.c \
+  $(TOP)/src/vdbe.h \
+  $(TOP)/src/vdbeapi.c \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbeblob.c \
+  $(TOP)/src/vdbemem.c \
+  $(TOP)/src/vdbesort.c \
+  $(TOP)/src/vdbetrace.c \
+  $(TOP)/src/vdbeInt.h \
+  $(TOP)/src/vtab.c \
+  $(TOP)/src/wal.c \
+  $(TOP)/src/wal.h \
+  $(TOP)/src/walker.c \
+  $(TOP)/src/where.c
+
+# Source code for extensions
+#
+SRC += \
+  $(TOP)/ext/fts1/fts1.c \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.c \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_porter.c \
+  $(TOP)/ext/fts1/fts1_tokenizer.h \
+  $(TOP)/ext/fts1/fts1_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts2/fts2.c \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.c \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_icu.c \
+  $(TOP)/ext/fts2/fts2_porter.c \
+  $(TOP)/ext/fts2/fts2_tokenizer.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.c \
+  $(TOP)/ext/fts2/fts2_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts3/fts3.c \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3Int.h \
+  $(TOP)/ext/fts3/fts3_aux.c \
+  $(TOP)/ext/fts3/fts3_expr.c \
+  $(TOP)/ext/fts3/fts3_hash.c \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_icu.c \
+  $(TOP)/ext/fts3/fts3_porter.c \
+  $(TOP)/ext/fts3/fts3_snippet.c \
+  $(TOP)/ext/fts3/fts3_tokenizer.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.c \
+  $(TOP)/ext/fts3/fts3_tokenizer1.c \
+  $(TOP)/ext/fts3/fts3_write.c
+SRC += \
+  $(TOP)/ext/icu/sqliteicu.h \
+  $(TOP)/ext/icu/icu.c
+SRC += \
+  $(TOP)/ext/rtree/rtree.h \
+  $(TOP)/ext/rtree/rtree.c
+
+
+# Generated source code files
+#
+SRC += \
+  keywordhash.h \
+  opcodes.c \
+  opcodes.h \
+  parse.c \
+  parse.h \
+  config.h \
+  sqlite3.h
+
+# Source code to the test files.
+#
+TESTSRC = \
+  $(TOP)/src/test1.c \
+  $(TOP)/src/test2.c \
+  $(TOP)/src/test3.c \
+  $(TOP)/src/test4.c \
+  $(TOP)/src/test5.c \
+  $(TOP)/src/test6.c \
+  $(TOP)/src/test7.c \
+  $(TOP)/src/test8.c \
+  $(TOP)/src/test9.c \
+  $(TOP)/src/test_autoext.c \
+  $(TOP)/src/test_async.c \
+  $(TOP)/src/test_backup.c \
+  $(TOP)/src/test_btree.c \
+  $(TOP)/src/test_config.c \
+  $(TOP)/src/test_demovfs.c \
+  $(TOP)/src/test_devsym.c \
+  $(TOP)/src/test_func.c \
+  $(TOP)/src/test_fuzzer.c \
+  $(TOP)/src/test_hexio.c \
+  $(TOP)/src/test_init.c \
+  $(TOP)/src/test_intarray.c \
+  $(TOP)/src/test_journal.c \
+  $(TOP)/src/test_malloc.c \
+  $(TOP)/src/test_multiplex.c \
+  $(TOP)/src/test_mutex.c \
+  $(TOP)/src/test_onefile.c \
+  $(TOP)/src/test_osinst.c \
+  $(TOP)/src/test_pcache.c \
+  $(TOP)/src/test_quota.c \
+  $(TOP)/src/test_rtree.c \
+  $(TOP)/src/test_schema.c \
+  $(TOP)/src/test_server.c \
+  $(TOP)/src/test_superlock.c \
+  $(TOP)/src/test_syscall.c \
+  $(TOP)/src/test_stat.c \
+  $(TOP)/src/test_tclvar.c \
+  $(TOP)/src/test_thread.c \
+  $(TOP)/src/test_vfs.c \
+  $(TOP)/src/test_wholenumber.c \
+  $(TOP)/src/test_wsd.c       \
+  $(TOP)/ext/fts3/fts3_term.c \
+  $(TOP)/ext/fts3/fts3_test.c 
+
+# Source code to the library files needed by the test fixture
+#
+TESTSRC2 = \
+  $(TOP)/src/attach.c \
+  $(TOP)/src/backup.c \
+  $(TOP)/src/bitvec.c \
+  $(TOP)/src/btree.c \
+  $(TOP)/src/build.c \
+  $(TOP)/src/ctime.c \
+  $(TOP)/src/date.c \
+  $(TOP)/src/expr.c \
+  $(TOP)/src/func.c \
+  $(TOP)/src/insert.c \
+  $(TOP)/src/wal.c \
+  $(TOP)/src/mem5.c \
+  $(TOP)/src/os.c \
+  $(TOP)/src/os_os2.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
+  $(TOP)/src/pager.c \
+  $(TOP)/src/pragma.c \
+  $(TOP)/src/prepare.c \
+  $(TOP)/src/printf.c \
+  $(TOP)/src/random.c \
+  $(TOP)/src/pcache.c \
+  $(TOP)/src/pcache1.c \
+  $(TOP)/src/select.c \
+  $(TOP)/src/tokenize.c \
+  $(TOP)/src/utf.c \
+  $(TOP)/src/util.c \
+  $(TOP)/src/vdbeapi.c \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbe.c \
+  $(TOP)/src/vdbemem.c \
+  $(TOP)/src/vdbetrace.c \
+  $(TOP)/src/where.c \
+  parse.c \
+  $(TOP)/ext/fts3/fts3.c \
+  $(TOP)/ext/fts3/fts3_aux.c \
+  $(TOP)/ext/fts3/fts3_expr.c \
+  $(TOP)/ext/fts3/fts3_term.c \
+  $(TOP)/ext/fts3/fts3_tokenizer.c \
+  $(TOP)/ext/fts3/fts3_write.c \
+  $(TOP)/ext/async/sqlite3async.c
+
+# Header files used by all library source files.
+#
+HDR = \
+   $(TOP)/src/btree.h \
+   $(TOP)/src/btreeInt.h \
+   $(TOP)/src/hash.h \
+   $(TOP)/src/hwtime.h \
+   keywordhash.h \
+   $(TOP)/src/mutex.h \
+   opcodes.h \
+   $(TOP)/src/os.h \
+   $(TOP)/src/os_common.h \
+   $(TOP)/src/pager.h \
+   $(TOP)/src/pcache.h \
+   parse.h  \
+   sqlite3.h  \
+   $(TOP)/src/sqlite3ext.h \
+   $(TOP)/src/sqliteInt.h  \
+   $(TOP)/src/sqliteLimit.h \
+   $(TOP)/src/vdbe.h \
+   $(TOP)/src/vdbeInt.h \
+   config.h
+
+# Header files used by extensions
+#
+EXTHDR += \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3Int.h \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/rtree/rtree.h
+EXTHDR += \
+  $(TOP)/ext/icu/sqliteicu.h
+EXTHDR += \
+  $(TOP)/ext/rtree/sqlite3rtree.h
+
+# This is the default Makefile target.  The objects listed here
+# are what get build when you type just "make" with no arguments.
+#
+all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
+
+Makefile: $(TOP)/Makefile.in
+	./config.status
+
+sqlite3.pc: $(TOP)/sqlite3.pc.in
+	./config.status
+
+libsqlite3.la:	$(LIBOBJ)
+	$(LTLINK) -o $@ $(LIBOBJ) $(TLIBS) \
+		${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8"
+
+libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
+	$(LTLINK) -o $@ tclsqlite.lo \
+		libsqlite3.la -L/usr/lib -ltclstub8.5 $(TLIBS) \
+		-rpath "$(TCLLIBDIR)" \
+		-version-info "8:6:8" \
+		-avoid-version
+
+sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
+	$(LTLINK) $(READLINE_FLAGS) \
+		-o $@ $(TOP)/src/shell.c libsqlite3.la \
+		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
+
+# This target creates a directory named "tsrc" and fills it with
+# copies of all of the C source code and header files needed to
+# build on the target system.  Some of the C source code and header
+# files are automatically generated.  This target takes care of
+# all that automatic generation.
+#
+.target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl
+	rm -rf tsrc
+	mkdir tsrc
+	cp -f $(SRC) tsrc
+	rm tsrc/sqlite.h.in tsrc/parse.y
+	$(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl <tsrc/vdbe.c >vdbe.new
+	mv vdbe.new tsrc/vdbe.c
+	touch .target_source
+
+sqlite3.c:	.target_source $(TOP)/tool/mksqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
+
+sqlite3-all.c:	sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
+
+# Rule to build the amalgamation
+#
+sqlite3.lo:	sqlite3.c
+	$(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c
+
+# Rules to build the LEMON compiler generator
+#
+lemon$(BEXE):	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
+	$(BCC) -o $@ $(TOP)/tool/lemon.c
+	cp $(TOP)/src/lempar.c .
+
+# Rules to build individual *.o files from generated *.c files. This
+# applies to:
+#
+#     parse.o
+#     opcodes.o
+#
+parse.lo:	parse.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c parse.c
+
+opcodes.lo:	opcodes.c
+	$(LTCOMPILE) $(TEMP_STORE) -c opcodes.c
+
+# Rules to build individual *.o files from files in the src directory.
+#
+alter.lo:	$(TOP)/src/alter.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c
+
+analyze.lo:	$(TOP)/src/analyze.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c
+
+attach.lo:	$(TOP)/src/attach.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c
+
+auth.lo:	$(TOP)/src/auth.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c
+
+backup.lo:	$(TOP)/src/backup.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c
+
+bitvec.lo:	$(TOP)/src/bitvec.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c
+
+btmutex.lo:	$(TOP)/src/btmutex.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c
+
+btree.lo:	$(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c
+
+build.lo:	$(TOP)/src/build.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c
+
+callback.lo:	$(TOP)/src/callback.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c
+
+complete.lo:	$(TOP)/src/complete.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c
+
+ctime.lo:	$(TOP)/src/ctime.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c
+
+date.lo:	$(TOP)/src/date.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
+
+delete.lo:	$(TOP)/src/delete.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
+
+expr.lo:	$(TOP)/src/expr.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c
+
+fault.lo:	$(TOP)/src/fault.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c
+
+fkey.lo:	$(TOP)/src/fkey.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c
+
+func.lo:	$(TOP)/src/func.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c
+
+global.lo:	$(TOP)/src/global.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c
+
+hash.lo:	$(TOP)/src/hash.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c
+
+insert.lo:	$(TOP)/src/insert.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c
+
+journal.lo:	$(TOP)/src/journal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/journal.c
+
+legacy.lo:	$(TOP)/src/legacy.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c
+
+loadext.lo:	$(TOP)/src/loadext.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c
+
+main.lo:	$(TOP)/src/main.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c
+
+malloc.lo:	$(TOP)/src/malloc.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c
+
+mem0.lo:	$(TOP)/src/mem0.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c
+
+mem1.lo:	$(TOP)/src/mem1.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c
+
+mem2.lo:	$(TOP)/src/mem2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c
+
+mem3.lo:	$(TOP)/src/mem3.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c
+
+mem5.lo:	$(TOP)/src/mem5.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c
+
+memjournal.lo:	$(TOP)/src/memjournal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c
+
+mutex.lo:	$(TOP)/src/mutex.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c
+
+mutex_noop.lo:	$(TOP)/src/mutex_noop.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c
+
+mutex_os2.lo:	$(TOP)/src/mutex_os2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_os2.c
+
+mutex_unix.lo:	$(TOP)/src/mutex_unix.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c
+
+mutex_w32.lo:	$(TOP)/src/mutex_w32.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c
+
+notify.lo:	$(TOP)/src/notify.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c
+
+pager.lo:	$(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c
+
+pcache.lo:	$(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c
+
+pcache1.lo:	$(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c
+
+os.lo:	$(TOP)/src/os.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c
+
+os_unix.lo:	$(TOP)/src/os_unix.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c
+
+os_win.lo:	$(TOP)/src/os_win.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c
+
+os_os2.lo:	$(TOP)/src/os_os2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_os2.c
+
+pragma.lo:	$(TOP)/src/pragma.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c
+
+prepare.lo:	$(TOP)/src/prepare.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c
+
+printf.lo:	$(TOP)/src/printf.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c
+
+random.lo:	$(TOP)/src/random.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c
+
+resolve.lo:	$(TOP)/src/resolve.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c
+
+rowset.lo:	$(TOP)/src/rowset.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c
+
+select.lo:	$(TOP)/src/select.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c
+
+status.lo:	$(TOP)/src/status.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c
+
+table.lo:	$(TOP)/src/table.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c
+
+tokenize.lo:	$(TOP)/src/tokenize.c keywordhash.h $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c
+
+trigger.lo:	$(TOP)/src/trigger.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c
+
+update.lo:	$(TOP)/src/update.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c
+
+utf.lo:	$(TOP)/src/utf.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c
+
+util.lo:	$(TOP)/src/util.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c
+
+vacuum.lo:	$(TOP)/src/vacuum.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c
+
+vdbe.lo:	$(TOP)/src/vdbe.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c
+
+vdbeapi.lo:	$(TOP)/src/vdbeapi.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c
+
+vdbeaux.lo:	$(TOP)/src/vdbeaux.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c
+
+vdbeblob.lo:	$(TOP)/src/vdbeblob.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c
+
+vdbemem.lo:	$(TOP)/src/vdbemem.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c
+
+vdbesort.lo:	$(TOP)/src/vdbesort.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c
+
+vdbetrace.lo:	$(TOP)/src/vdbetrace.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c
+
+vtab.lo:	$(TOP)/src/vtab.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c
+
+wal.lo:	$(TOP)/src/wal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c
+
+walker.lo:	$(TOP)/src/walker.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c
+
+where.lo:	$(TOP)/src/where.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c
+
+tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
+
+tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
+
+tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
+
+tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
+	$(LTLINK) -o $@ tclsqlite-shell.lo \
+		 libsqlite3.la $(LIBTCL)
+
+# Rules to build opcodes.c and opcodes.h
+#
+opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
+	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
+
+opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
+	cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
+
+# Rules to build parse.c and parse.h - the outputs of lemon.
+#
+parse.h:	parse.c
+
+parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
+	cp $(TOP)/src/parse.y .
+	rm -f parse.h
+	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
+	mv parse.h parse.h.temp
+	$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
+
+sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
+	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
+
+keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
+	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
+	./mkkeywordhash$(BEXE) >keywordhash.h
+
+
+
+# Rules to build the extension objects.
+#
+icu.lo:	$(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
+
+fts2.lo:	$(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
+
+fts2_hash.lo:	$(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
+
+fts2_icu.lo:	$(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
+
+fts2_porter.lo:	$(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
+
+fts2_tokenizer.lo:	$(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
+
+fts2_tokenizer1.lo:	$(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
+
+fts3.lo:	$(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
+
+fts3_aux.lo:	$(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c
+
+fts3_expr.lo:	$(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
+
+fts3_hash.lo:	$(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
+
+fts3_icu.lo:	$(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
+
+fts3_porter.lo:	$(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
+
+fts3_snippet.lo:	$(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c
+
+fts3_tokenizer.lo:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
+
+fts3_tokenizer1.lo:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
+
+fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
+
+rtree.lo:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
+
+
+# Rules to build the 'testfixture' application.
+#
+# If using the amalgamation, use sqlite3.c directly to build the test
+# fixture.  Otherwise link against libsqlite3.la.  (This distinction is
+# necessary because the test fixture requires non-API symbols which are
+# hidden when the library is built via the amalgamation).
+#
+TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
+TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
+TESTFIXTURE_FLAGS += -DBUILD_sqlite
+
+TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
+TESTFIXTURE_SRC1 = sqlite3.c
+TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
+
+testfixture$(TEXE):	$(TESTFIXTURE_SRC)
+	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
+		-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
+
+
+fulltest:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/all.test
+
+soaktest:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
+
+test:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/veryquick.test
+
+sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
+	echo "#define TCLSH 2" > $@
+	cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@
+	echo "static const char *tclsh_main_loop(void){" >> $@
+	echo "static const char *zMainloop = " >> $@
+	$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
+	echo "; return zMainloop; }" >> $@
+
+sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
+	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
+
+# Standard install and cleanup targets
+#
+lib_install:	libsqlite3.la
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
+	
+install:	sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
+	$(INSTALL) -d $(DESTDIR)$(includedir)
+	$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
+	$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
+	$(INSTALL) -d $(DESTDIR)$(pkgconfigdir)
+	$(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
+
+pkgIndex.tcl:
+	echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3.so sqlite3]' > $@
+tcl_install:	lib_install libtclsqlite3.la pkgIndex.tcl
+	$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
+	$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
+	rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
+	$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
+
+clean:	
+	rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
+	rm -f sqlite3.h opcodes.*
+	rm -rf .libs .deps
+	rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
+	rm -f mkkeywordhash$(BEXE) keywordhash.h
+	rm -f $(PUBLISH)
+	rm -f *.da *.bb *.bbg gmon.out
+	rm -rf tsrc .target_source
+	rm -f tclsqlite3$(TEXE)
+	rm -f testfixture$(TEXE) test.db
+	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
+	rm -f sqlite3.c
+	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
+
+distclean:	clean
+	rm -f config.log config.status libtool Makefile sqlite3.pc
+
+#
+# Windows section
+#
+dll: sqlite3.dll
+
+REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o)
+
+$(REAL_LIBOBJ): $(LIBOBJ)
+
+sqlite3.def: $(REAL_LIBOBJ)
+	echo 'EXPORTS' >sqlite3.def
+	nm $(REAL_LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \
+		| sed 's/^.* _//' >>sqlite3.def
+
+sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def
+	$(TCC) -shared -o $@ sqlite3.def \
+		-Wl,"--strip-all" $(REAL_LIBOBJ)

+ 138 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.arm-wince-mingw32ce-gcc

@@ -0,0 +1,138 @@
+#!/usr/make
+#
+# Makefile for SQLITE
+#
+# This is a template makefile for SQLite.  Most people prefer to
+# use the autoconf generated "configure" script to generate the
+# makefile automatically.  But that does not work for everybody
+# and in every situation.  If you are having problems with the
+# "configure" script, you might want to try this makefile as an
+# alternative.  Create a copy of this file, edit the parameters
+# below and type "make".
+#
+
+#### The directory where to find the mingw32ce tools
+MINGW32CE = /opt/mingw32ce/bin
+
+#### The target prefix of the mingw32ce tools
+TARGET = arm-wince-mingw32ce
+
+#### The toplevel directory of the source tree.  This is the directory
+#    that contains this "Makefile.in" and the "configure.in" script.
+#
+TOP = ../sqlite
+
+#### C Compiler and options for use in building executables that
+#    will run on the platform that is doing the build.
+#
+BCC = gcc -g -O2
+#BCC = /opt/ancic/bin/c89 -0
+
+#### If the target operating system supports the "usleep()" system
+#    call, then define the HAVE_USLEEP macro for all C modules.
+#
+USLEEP = 
+#USLEEP = -DHAVE_USLEEP=1
+
+#### If you want the SQLite library to be safe for use within a 
+#    multi-threaded program, then define the following macro
+#    appropriately:
+#
+THREADSAFE = -DTHREADSAFE=1
+#THREADSAFE = -DTHREADSAFE=0
+
+#### Specify any extra linker options needed to make the library
+#    thread safe
+#
+#THREADLIB = -lpthread
+THREADLIB = 
+
+#### Specify any extra libraries needed to access required functions.
+#
+#TLIBS = -lrt    # fdatasync on Solaris 8
+TLIBS = 
+
+#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
+#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
+#    malloc()s and free()s in order to track down memory leaks.
+#    
+#    SQLite uses some expensive assert() statements in the inner loop.
+#    You can make the library go almost twice as fast if you compile
+#    with -DNDEBUG=1
+#
+#OPTS = -DSQLITE_DEBUG=2
+#OPTS = -DSQLITE_DEBUG=1
+#OPTS = 
+OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
+#OPTS += -DHAVE_FDATASYNC=1
+
+#### The suffix to add to executable files.  ".exe" for windows.
+#    Nothing for unix.
+#
+EXE = .exe
+#EXE =
+
+#### C Compile and options for use in building executables that 
+#    will run on the target platform.  This is usually the same
+#    as BCC, unless you are cross-compiling.
+#
+#TCC = gcc -O6
+#TCC = gcc -g -O0 -Wall
+#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
+#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
+TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
+#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
+
+#### Tools used to build a static library.
+#
+#AR = ar cr
+#AR = /opt/mingw/bin/i386-mingw32-ar cr
+AR = $(MINGW32CE)/$(TARGET)-ar cr
+#RANLIB = ranlib
+#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
+RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
+
+#MKSHLIB = gcc -shared
+#SO = so
+#SHPREFIX = lib
+MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
+SO = dll
+SHPREFIX =
+
+#### Extra compiler options needed for programs that use the TCL library.
+#
+#TCL_FLAGS =
+#TCL_FLAGS = -DSTATIC_BUILD=1
+TCL_FLAGS = -I/home/drh/tcltk/8.5linux
+#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
+#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
+
+#### Linker options needed to link against the TCL library.
+#
+#LIBTCL = -ltcl -lm -ldl
+LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
+#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
+#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
+
+#### Additional objects for SQLite library when TCL support is enabled.
+TCLOBJ =
+#TCLOBJ = tclsqlite.o
+
+#### Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS =
+#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
+
+#### Linker options needed by programs using readline() must link against.
+#
+LIBREADLINE =
+#LIBREADLINE = -static -lreadline -ltermcap
+
+#### Which "awk" program provides nawk compatibilty
+#
+# NAWK = nawk
+NAWK = awk
+
+# You should not have to change anything below this line
+###############################################################################
+include $(TOP)/main.mk

+ 957 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.in

@@ -0,0 +1,957 @@
+#!/usr/make
+#
+# Makefile for SQLITE
+#
+# This makefile is suppose to be configured automatically using the
+# autoconf.  But if that does not work for you, you can configure
+# the makefile manually.  Just set the parameters below to values that
+# work well for your system.
+#
+# If the configure script does not work out-of-the-box, you might
+# be able to get it to work by giving it some hints.  See the comment
+# at the beginning of configure.in for additional information.
+#
+
+# The toplevel directory of the source tree.  This is the directory
+# that contains this "Makefile.in" and the "configure.in" script.
+#
+TOP = @srcdir@
+
+# C Compiler and options for use in building executables that
+# will run on the platform that is doing the build.
+#
+BCC = @BUILD_CC@ @BUILD_CFLAGS@
+
+# C Compile and options for use in building executables that 
+# will run on the target platform.  (BCC and TCC are usually the
+# same unless your are cross-compiling.)
+#
+TCC = @CC@ @CPPFLAGS@ @CFLAGS@ -I. -I${TOP}/src -I${TOP}/ext/rtree
+
+# Define this for the autoconf-based build, so that the code knows it can
+# include the generated config.h
+# 
+TCC += -D_HAVE_SQLITE_CONFIG_H
+
+# Define -DNDEBUG to compile without debugging (i.e., for production usage)
+# Omitting the define will cause extra debugging code to be inserted and
+# includes extra comments when "EXPLAIN stmt" is used.
+#
+TCC += @TARGET_DEBUG@ @XTHREADCONNECT@
+
+# Compiler options needed for programs that use the TCL library.
+#
+TCC += @TCL_INCLUDE_SPEC@
+
+# The library that programs using TCL must link against.
+#
+LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@
+
+# Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@
+
+# The library that programs using readline() must link against.
+#
+LIBREADLINE = @TARGET_READLINE_LIBS@
+
+# Should the database engine be compiled threadsafe
+#
+TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
+
+# Any target libraries which libsqlite must be linked against
+# 
+TLIBS = @LIBS@
+
+# Flags controlling use of the in memory btree implementation
+#
+# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
+# default to file, 2 to default to memory, and 3 to force temporary
+# tables to always be in memory.
+#
+TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
+
+# Enable/disable loadable extensions, and other optional features
+# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).  
+# The same set of OMIT and ENABLE flags should be passed to the 
+# LEMON parser generator and the mkkeywordhash tool as well.
+OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
+
+TCC += $(OPT_FEATURE_FLAGS)
+
+# Add in any optional parameters specified on the make commane line
+# ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
+TCC += $(OPTS)
+
+# Version numbers and release number for the SQLite being compiled.
+#
+VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
+RELEASE = @RELEASE@
+
+# Filename extensions
+#
+BEXE = @BUILD_EXEEXT@
+TEXE = @TARGET_EXEEXT@
+
+# The following variable is "1" if the configure script was able to locate
+# the tclConfig.sh file.  It is an empty string otherwise.  When this
+# variable is "1", the TCL extension library (libtclsqlite3.so) is built
+# and installed.
+#
+HAVE_TCL = @HAVE_TCL@
+
+# This is the command to use for tclsh - normally just "tclsh", but we may
+# know the specific version we want to use
+#
+TCLSH_CMD = @TCLSH_CMD@
+
+# Where do we want to install the tcl plugin
+#
+TCLLIBDIR = @TCLLIBDIR@
+
+# The suffix used on shared libraries.  Ex:  ".dll", ".so", ".dylib"
+#
+SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
+
+# If gcov support was enabled by the configure script, add the appropriate
+# flags here.  It's not always as easy as just having the user add the right
+# CFLAGS / LDFLAGS, because libtool wants to use CFLAGS when linking, which
+# causes build errors with -fprofile-arcs -ftest-coverage with some GCCs.  
+# Supposedly GCC does the right thing if you use --coverage, but in 
+# practice it still fails.  See:
+#
+# http://www.mail-archive.com/debian-gcc@lists.debian.org/msg26197.html
+#
+# for more info.
+#
+GCOV_CFLAGS1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage
+GCOV_LDFLAGS1 = -lgcov
+USE_GCOV = @USE_GCOV@
+LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
+LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
+
+
+# The directory into which to store package information for
+
+# Some standard variables and programs
+#
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+pkgconfigdir = $(libdir)/pkgconfig
+bindir = @bindir@
+includedir = @includedir@
+INSTALL = @INSTALL@
+LIBTOOL = ./libtool
+ALLOWRELEASE = @ALLOWRELEASE@
+
+# libtool compile/link/install
+LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
+LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS)
+LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
+
+# nawk compatible awk.
+NAWK = @AWK@
+
+# You should not have to change anything below this line
+###############################################################################
+
+USE_AMALGAMATION = @USE_AMALGAMATION@
+
+# Object files for the SQLite library (non-amalgamation).
+#
+LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
+         backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
+         callback.lo complete.lo ctime.lo date.lo delete.lo \
+         expr.lo fault.lo fkey.lo \
+         fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \
+         fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \
+         func.lo global.lo hash.lo \
+         icu.lo insert.lo journal.lo legacy.lo loadext.lo \
+         main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
+         memjournal.lo \
+         mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
+         notify.lo opcodes.lo os.lo os_os2.lo os_unix.lo os_win.lo \
+         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
+         random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
+         table.lo tokenize.lo trigger.lo \
+         update.lo util.lo vacuum.lo \
+         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
+         vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
+
+# Object files for the amalgamation.
+#
+LIBOBJS1 = sqlite3.lo
+
+# Determine the real value of LIBOBJ based on the 'configure' script
+#
+LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION))
+
+
+# All of the source code files.
+#
+SRC = \
+  $(TOP)/src/alter.c \
+  $(TOP)/src/analyze.c \
+  $(TOP)/src/attach.c \
+  $(TOP)/src/auth.c \
+  $(TOP)/src/backup.c \
+  $(TOP)/src/bitvec.c \
+  $(TOP)/src/btmutex.c \
+  $(TOP)/src/btree.c \
+  $(TOP)/src/btree.h \
+  $(TOP)/src/btreeInt.h \
+  $(TOP)/src/build.c \
+  $(TOP)/src/callback.c \
+  $(TOP)/src/complete.c \
+  $(TOP)/src/ctime.c \
+  $(TOP)/src/date.c \
+  $(TOP)/src/delete.c \
+  $(TOP)/src/expr.c \
+  $(TOP)/src/fault.c \
+  $(TOP)/src/fkey.c \
+  $(TOP)/src/func.c \
+  $(TOP)/src/global.c \
+  $(TOP)/src/hash.c \
+  $(TOP)/src/hash.h \
+  $(TOP)/src/hwtime.h \
+  $(TOP)/src/insert.c \
+  $(TOP)/src/journal.c \
+  $(TOP)/src/legacy.c \
+  $(TOP)/src/loadext.c \
+  $(TOP)/src/main.c \
+  $(TOP)/src/malloc.c \
+  $(TOP)/src/mem0.c \
+  $(TOP)/src/mem1.c \
+  $(TOP)/src/mem2.c \
+  $(TOP)/src/mem3.c \
+  $(TOP)/src/mem5.c \
+  $(TOP)/src/memjournal.c \
+  $(TOP)/src/mutex.c \
+  $(TOP)/src/mutex.h \
+  $(TOP)/src/mutex_noop.c \
+  $(TOP)/src/mutex_os2.c \
+  $(TOP)/src/mutex_unix.c \
+  $(TOP)/src/mutex_w32.c \
+  $(TOP)/src/notify.c \
+  $(TOP)/src/os.c \
+  $(TOP)/src/os.h \
+  $(TOP)/src/os_common.h \
+  $(TOP)/src/os_os2.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
+  $(TOP)/src/pager.c \
+  $(TOP)/src/pager.h \
+  $(TOP)/src/parse.y \
+  $(TOP)/src/pcache.c \
+  $(TOP)/src/pcache.h \
+  $(TOP)/src/pcache1.c \
+  $(TOP)/src/pragma.c \
+  $(TOP)/src/prepare.c \
+  $(TOP)/src/printf.c \
+  $(TOP)/src/random.c \
+  $(TOP)/src/resolve.c \
+  $(TOP)/src/rowset.c \
+  $(TOP)/src/select.c \
+  $(TOP)/src/status.c \
+  $(TOP)/src/shell.c \
+  $(TOP)/src/sqlite.h.in \
+  $(TOP)/src/sqlite3ext.h \
+  $(TOP)/src/sqliteInt.h \
+  $(TOP)/src/sqliteLimit.h \
+  $(TOP)/src/table.c \
+  $(TOP)/src/tclsqlite.c \
+  $(TOP)/src/tokenize.c \
+  $(TOP)/src/trigger.c \
+  $(TOP)/src/utf.c \
+  $(TOP)/src/update.c \
+  $(TOP)/src/util.c \
+  $(TOP)/src/vacuum.c \
+  $(TOP)/src/vdbe.c \
+  $(TOP)/src/vdbe.h \
+  $(TOP)/src/vdbeapi.c \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbeblob.c \
+  $(TOP)/src/vdbemem.c \
+  $(TOP)/src/vdbesort.c \
+  $(TOP)/src/vdbetrace.c \
+  $(TOP)/src/vdbeInt.h \
+  $(TOP)/src/vtab.c \
+  $(TOP)/src/wal.c \
+  $(TOP)/src/wal.h \
+  $(TOP)/src/walker.c \
+  $(TOP)/src/where.c
+
+# Source code for extensions
+#
+SRC += \
+  $(TOP)/ext/fts1/fts1.c \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.c \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_porter.c \
+  $(TOP)/ext/fts1/fts1_tokenizer.h \
+  $(TOP)/ext/fts1/fts1_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts2/fts2.c \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.c \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_icu.c \
+  $(TOP)/ext/fts2/fts2_porter.c \
+  $(TOP)/ext/fts2/fts2_tokenizer.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.c \
+  $(TOP)/ext/fts2/fts2_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts3/fts3.c \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3Int.h \
+  $(TOP)/ext/fts3/fts3_aux.c \
+  $(TOP)/ext/fts3/fts3_expr.c \
+  $(TOP)/ext/fts3/fts3_hash.c \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_icu.c \
+  $(TOP)/ext/fts3/fts3_porter.c \
+  $(TOP)/ext/fts3/fts3_snippet.c \
+  $(TOP)/ext/fts3/fts3_tokenizer.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.c \
+  $(TOP)/ext/fts3/fts3_tokenizer1.c \
+  $(TOP)/ext/fts3/fts3_write.c
+SRC += \
+  $(TOP)/ext/icu/sqliteicu.h \
+  $(TOP)/ext/icu/icu.c
+SRC += \
+  $(TOP)/ext/rtree/rtree.h \
+  $(TOP)/ext/rtree/rtree.c
+
+
+# Generated source code files
+#
+SRC += \
+  keywordhash.h \
+  opcodes.c \
+  opcodes.h \
+  parse.c \
+  parse.h \
+  config.h \
+  sqlite3.h
+
+# Source code to the test files.
+#
+TESTSRC = \
+  $(TOP)/src/test1.c \
+  $(TOP)/src/test2.c \
+  $(TOP)/src/test3.c \
+  $(TOP)/src/test4.c \
+  $(TOP)/src/test5.c \
+  $(TOP)/src/test6.c \
+  $(TOP)/src/test7.c \
+  $(TOP)/src/test8.c \
+  $(TOP)/src/test9.c \
+  $(TOP)/src/test_autoext.c \
+  $(TOP)/src/test_async.c \
+  $(TOP)/src/test_backup.c \
+  $(TOP)/src/test_btree.c \
+  $(TOP)/src/test_config.c \
+  $(TOP)/src/test_demovfs.c \
+  $(TOP)/src/test_devsym.c \
+  $(TOP)/src/test_func.c \
+  $(TOP)/src/test_fuzzer.c \
+  $(TOP)/src/test_hexio.c \
+  $(TOP)/src/test_init.c \
+  $(TOP)/src/test_intarray.c \
+  $(TOP)/src/test_journal.c \
+  $(TOP)/src/test_malloc.c \
+  $(TOP)/src/test_multiplex.c \
+  $(TOP)/src/test_mutex.c \
+  $(TOP)/src/test_onefile.c \
+  $(TOP)/src/test_osinst.c \
+  $(TOP)/src/test_pcache.c \
+  $(TOP)/src/test_quota.c \
+  $(TOP)/src/test_rtree.c \
+  $(TOP)/src/test_schema.c \
+  $(TOP)/src/test_server.c \
+  $(TOP)/src/test_superlock.c \
+  $(TOP)/src/test_syscall.c \
+  $(TOP)/src/test_stat.c \
+  $(TOP)/src/test_tclvar.c \
+  $(TOP)/src/test_thread.c \
+  $(TOP)/src/test_vfs.c \
+  $(TOP)/src/test_wholenumber.c \
+  $(TOP)/src/test_wsd.c       \
+  $(TOP)/ext/fts3/fts3_term.c \
+  $(TOP)/ext/fts3/fts3_test.c 
+
+# Source code to the library files needed by the test fixture
+#
+TESTSRC2 = \
+  $(TOP)/src/attach.c \
+  $(TOP)/src/backup.c \
+  $(TOP)/src/bitvec.c \
+  $(TOP)/src/btree.c \
+  $(TOP)/src/build.c \
+  $(TOP)/src/ctime.c \
+  $(TOP)/src/date.c \
+  $(TOP)/src/expr.c \
+  $(TOP)/src/func.c \
+  $(TOP)/src/insert.c \
+  $(TOP)/src/wal.c \
+  $(TOP)/src/mem5.c \
+  $(TOP)/src/os.c \
+  $(TOP)/src/os_os2.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
+  $(TOP)/src/pager.c \
+  $(TOP)/src/pragma.c \
+  $(TOP)/src/prepare.c \
+  $(TOP)/src/printf.c \
+  $(TOP)/src/random.c \
+  $(TOP)/src/pcache.c \
+  $(TOP)/src/pcache1.c \
+  $(TOP)/src/select.c \
+  $(TOP)/src/tokenize.c \
+  $(TOP)/src/utf.c \
+  $(TOP)/src/util.c \
+  $(TOP)/src/vdbeapi.c \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbe.c \
+  $(TOP)/src/vdbemem.c \
+  $(TOP)/src/vdbetrace.c \
+  $(TOP)/src/where.c \
+  parse.c \
+  $(TOP)/ext/fts3/fts3.c \
+  $(TOP)/ext/fts3/fts3_aux.c \
+  $(TOP)/ext/fts3/fts3_expr.c \
+  $(TOP)/ext/fts3/fts3_term.c \
+  $(TOP)/ext/fts3/fts3_tokenizer.c \
+  $(TOP)/ext/fts3/fts3_write.c \
+  $(TOP)/ext/async/sqlite3async.c
+
+# Header files used by all library source files.
+#
+HDR = \
+   $(TOP)/src/btree.h \
+   $(TOP)/src/btreeInt.h \
+   $(TOP)/src/hash.h \
+   $(TOP)/src/hwtime.h \
+   keywordhash.h \
+   $(TOP)/src/mutex.h \
+   opcodes.h \
+   $(TOP)/src/os.h \
+   $(TOP)/src/os_common.h \
+   $(TOP)/src/pager.h \
+   $(TOP)/src/pcache.h \
+   parse.h  \
+   sqlite3.h  \
+   $(TOP)/src/sqlite3ext.h \
+   $(TOP)/src/sqliteInt.h  \
+   $(TOP)/src/sqliteLimit.h \
+   $(TOP)/src/vdbe.h \
+   $(TOP)/src/vdbeInt.h \
+   config.h
+
+# Header files used by extensions
+#
+EXTHDR += \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3Int.h \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/rtree/rtree.h
+EXTHDR += \
+  $(TOP)/ext/icu/sqliteicu.h
+EXTHDR += \
+  $(TOP)/ext/rtree/sqlite3rtree.h
+
+# This is the default Makefile target.  The objects listed here
+# are what get build when you type just "make" with no arguments.
+#
+all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
+
+Makefile: $(TOP)/Makefile.in
+	./config.status
+
+sqlite3.pc: $(TOP)/sqlite3.pc.in
+	./config.status
+
+libsqlite3.la:	$(LIBOBJ)
+	$(LTLINK) -o $@ $(LIBOBJ) $(TLIBS) \
+		${ALLOWRELEASE} -rpath "$(libdir)" -version-info "8:6:8"
+
+libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
+	$(LTLINK) -o $@ tclsqlite.lo \
+		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
+		-rpath "$(TCLLIBDIR)" \
+		-version-info "8:6:8" \
+		-avoid-version
+
+sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
+	$(LTLINK) $(READLINE_FLAGS) \
+		-o $@ $(TOP)/src/shell.c libsqlite3.la \
+		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
+
+# This target creates a directory named "tsrc" and fills it with
+# copies of all of the C source code and header files needed to
+# build on the target system.  Some of the C source code and header
+# files are automatically generated.  This target takes care of
+# all that automatic generation.
+#
+.target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl
+	rm -rf tsrc
+	mkdir tsrc
+	cp -f $(SRC) tsrc
+	rm tsrc/sqlite.h.in tsrc/parse.y
+	$(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl <tsrc/vdbe.c >vdbe.new
+	mv vdbe.new tsrc/vdbe.c
+	touch .target_source
+
+sqlite3.c:	.target_source $(TOP)/tool/mksqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
+
+sqlite3-all.c:	sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
+
+# Rule to build the amalgamation
+#
+sqlite3.lo:	sqlite3.c
+	$(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c
+
+# Rules to build the LEMON compiler generator
+#
+lemon$(BEXE):	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
+	$(BCC) -o $@ $(TOP)/tool/lemon.c
+	cp $(TOP)/src/lempar.c .
+
+# Rules to build individual *.o files from generated *.c files. This
+# applies to:
+#
+#     parse.o
+#     opcodes.o
+#
+parse.lo:	parse.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c parse.c
+
+opcodes.lo:	opcodes.c
+	$(LTCOMPILE) $(TEMP_STORE) -c opcodes.c
+
+# Rules to build individual *.o files from files in the src directory.
+#
+alter.lo:	$(TOP)/src/alter.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/alter.c
+
+analyze.lo:	$(TOP)/src/analyze.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/analyze.c
+
+attach.lo:	$(TOP)/src/attach.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/attach.c
+
+auth.lo:	$(TOP)/src/auth.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/auth.c
+
+backup.lo:	$(TOP)/src/backup.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/backup.c
+
+bitvec.lo:	$(TOP)/src/bitvec.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/bitvec.c
+
+btmutex.lo:	$(TOP)/src/btmutex.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btmutex.c
+
+btree.lo:	$(TOP)/src/btree.c $(HDR) $(TOP)/src/pager.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/btree.c
+
+build.lo:	$(TOP)/src/build.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/build.c
+
+callback.lo:	$(TOP)/src/callback.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/callback.c
+
+complete.lo:	$(TOP)/src/complete.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/complete.c
+
+ctime.lo:	$(TOP)/src/ctime.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c
+
+date.lo:	$(TOP)/src/date.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
+
+delete.lo:	$(TOP)/src/delete.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
+
+expr.lo:	$(TOP)/src/expr.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/expr.c
+
+fault.lo:	$(TOP)/src/fault.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fault.c
+
+fkey.lo:	$(TOP)/src/fkey.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/fkey.c
+
+func.lo:	$(TOP)/src/func.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/func.c
+
+global.lo:	$(TOP)/src/global.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/global.c
+
+hash.lo:	$(TOP)/src/hash.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/hash.c
+
+insert.lo:	$(TOP)/src/insert.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c
+
+journal.lo:	$(TOP)/src/journal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/journal.c
+
+legacy.lo:	$(TOP)/src/legacy.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c
+
+loadext.lo:	$(TOP)/src/loadext.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c
+
+main.lo:	$(TOP)/src/main.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c
+
+malloc.lo:	$(TOP)/src/malloc.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c
+
+mem0.lo:	$(TOP)/src/mem0.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem0.c
+
+mem1.lo:	$(TOP)/src/mem1.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem1.c
+
+mem2.lo:	$(TOP)/src/mem2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem2.c
+
+mem3.lo:	$(TOP)/src/mem3.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c
+
+mem5.lo:	$(TOP)/src/mem5.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c
+
+memjournal.lo:	$(TOP)/src/memjournal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c
+
+mutex.lo:	$(TOP)/src/mutex.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c
+
+mutex_noop.lo:	$(TOP)/src/mutex_noop.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_noop.c
+
+mutex_os2.lo:	$(TOP)/src/mutex_os2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_os2.c
+
+mutex_unix.lo:	$(TOP)/src/mutex_unix.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_unix.c
+
+mutex_w32.lo:	$(TOP)/src/mutex_w32.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex_w32.c
+
+notify.lo:	$(TOP)/src/notify.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/notify.c
+
+pager.lo:	$(TOP)/src/pager.c $(HDR) $(TOP)/src/pager.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pager.c
+
+pcache.lo:	$(TOP)/src/pcache.c $(HDR) $(TOP)/src/pcache.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache.c
+
+pcache1.lo:	$(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pcache1.c
+
+os.lo:	$(TOP)/src/os.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c
+
+os_unix.lo:	$(TOP)/src/os_unix.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c
+
+os_win.lo:	$(TOP)/src/os_win.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_win.c
+
+os_os2.lo:	$(TOP)/src/os_os2.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_os2.c
+
+pragma.lo:	$(TOP)/src/pragma.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/pragma.c
+
+prepare.lo:	$(TOP)/src/prepare.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c
+
+printf.lo:	$(TOP)/src/printf.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/printf.c
+
+random.lo:	$(TOP)/src/random.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/random.c
+
+resolve.lo:	$(TOP)/src/resolve.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c
+
+rowset.lo:	$(TOP)/src/rowset.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c
+
+select.lo:	$(TOP)/src/select.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/select.c
+
+status.lo:	$(TOP)/src/status.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/status.c
+
+table.lo:	$(TOP)/src/table.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/table.c
+
+tokenize.lo:	$(TOP)/src/tokenize.c keywordhash.h $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/tokenize.c
+
+trigger.lo:	$(TOP)/src/trigger.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c
+
+update.lo:	$(TOP)/src/update.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c
+
+utf.lo:	$(TOP)/src/utf.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c
+
+util.lo:	$(TOP)/src/util.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c
+
+vacuum.lo:	$(TOP)/src/vacuum.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vacuum.c
+
+vdbe.lo:	$(TOP)/src/vdbe.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbe.c
+
+vdbeapi.lo:	$(TOP)/src/vdbeapi.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeapi.c
+
+vdbeaux.lo:	$(TOP)/src/vdbeaux.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeaux.c
+
+vdbeblob.lo:	$(TOP)/src/vdbeblob.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbeblob.c
+
+vdbemem.lo:	$(TOP)/src/vdbemem.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbemem.c
+
+vdbesort.lo:	$(TOP)/src/vdbesort.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbesort.c
+
+vdbetrace.lo:	$(TOP)/src/vdbetrace.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c
+
+vtab.lo:	$(TOP)/src/vtab.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c
+
+wal.lo:	$(TOP)/src/wal.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wal.c
+
+walker.lo:	$(TOP)/src/walker.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/walker.c
+
+where.lo:	$(TOP)/src/where.c $(HDR)
+	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/where.c
+
+tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
+
+tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
+
+tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
+
+tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
+	$(LTLINK) -o $@ tclsqlite-shell.lo \
+		 libsqlite3.la $(LIBTCL)
+
+# Rules to build opcodes.c and opcodes.h
+#
+opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
+	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
+
+opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
+	cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
+
+# Rules to build parse.c and parse.h - the outputs of lemon.
+#
+parse.h:	parse.c
+
+parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
+	cp $(TOP)/src/parse.y .
+	rm -f parse.h
+	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
+	mv parse.h parse.h.temp
+	$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
+
+sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
+	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
+
+keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
+	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
+	./mkkeywordhash$(BEXE) >keywordhash.h
+
+
+
+# Rules to build the extension objects.
+#
+icu.lo:	$(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
+
+fts2.lo:	$(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
+
+fts2_hash.lo:	$(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
+
+fts2_icu.lo:	$(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
+
+fts2_porter.lo:	$(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
+
+fts2_tokenizer.lo:	$(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
+
+fts2_tokenizer1.lo:	$(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
+
+fts3.lo:	$(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
+
+fts3_aux.lo:	$(TOP)/ext/fts3/fts3_aux.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_aux.c
+
+fts3_expr.lo:	$(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
+
+fts3_hash.lo:	$(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
+
+fts3_icu.lo:	$(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
+
+fts3_porter.lo:	$(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
+
+fts3_snippet.lo:	$(TOP)/ext/fts3/fts3_snippet.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_snippet.c
+
+fts3_tokenizer.lo:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
+
+fts3_tokenizer1.lo:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
+
+fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
+
+rtree.lo:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
+
+
+# Rules to build the 'testfixture' application.
+#
+# If using the amalgamation, use sqlite3.c directly to build the test
+# fixture.  Otherwise link against libsqlite3.la.  (This distinction is
+# necessary because the test fixture requires non-API symbols which are
+# hidden when the library is built via the amalgamation).
+#
+TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
+TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
+TESTFIXTURE_FLAGS += -DBUILD_sqlite
+
+TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
+TESTFIXTURE_SRC1 = sqlite3.c
+TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
+
+testfixture$(TEXE):	$(TESTFIXTURE_SRC)
+	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \
+		-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
+
+
+fulltest:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/all.test
+
+soaktest:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
+
+test:	testfixture$(TEXE) sqlite3$(TEXE)
+	./testfixture$(TEXE) $(TOP)/test/veryquick.test
+
+sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
+	echo "#define TCLSH 2" > $@
+	cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@
+	echo "static const char *tclsh_main_loop(void){" >> $@
+	echo "static const char *zMainloop = " >> $@
+	$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
+	echo "; return zMainloop; }" >> $@
+
+sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
+	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
+
+# Standard install and cleanup targets
+#
+lib_install:	libsqlite3.la
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
+	
+install:	sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
+	$(INSTALL) -d $(DESTDIR)$(includedir)
+	$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
+	$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
+	$(INSTALL) -d $(DESTDIR)$(pkgconfigdir)
+	$(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
+
+pkgIndex.tcl:
+	echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3.so sqlite3]' > $@
+tcl_install:	lib_install libtclsqlite3.la pkgIndex.tcl
+	$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
+	$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
+	rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
+	$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
+
+clean:	
+	rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
+	rm -f sqlite3.h opcodes.*
+	rm -rf .libs .deps
+	rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
+	rm -f mkkeywordhash$(BEXE) keywordhash.h
+	rm -f $(PUBLISH)
+	rm -f *.da *.bb *.bbg gmon.out
+	rm -rf tsrc .target_source
+	rm -f tclsqlite3$(TEXE)
+	rm -f testfixture$(TEXE) test.db
+	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
+	rm -f sqlite3.c
+	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
+
+distclean:	clean
+	rm -f config.log config.status libtool Makefile sqlite3.pc
+
+#
+# Windows section
+#
+dll: sqlite3.dll
+
+REAL_LIBOBJ = $(LIBOBJ:%.lo=.libs/%.o)
+
+$(REAL_LIBOBJ): $(LIBOBJ)
+
+sqlite3.def: $(REAL_LIBOBJ)
+	echo 'EXPORTS' >sqlite3.def
+	nm $(REAL_LIBOBJ) | grep ' T ' | grep ' _sqlite3_' \
+		| sed 's/^.* _//' >>sqlite3.def
+
+sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def
+	$(TCC) -shared -o $@ sqlite3.def \
+		-Wl,"--strip-all" $(REAL_LIBOBJ)

+ 128 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.linux-gcc

@@ -0,0 +1,128 @@
+#!/usr/make
+#
+# Makefile for SQLITE
+#
+# This is a template makefile for SQLite.  Most people prefer to
+# use the autoconf generated "configure" script to generate the
+# makefile automatically.  But that does not work for everybody
+# and in every situation.  If you are having problems with the
+# "configure" script, you might want to try this makefile as an
+# alternative.  Create a copy of this file, edit the parameters
+# below and type "make".
+#
+
+#### The toplevel directory of the source tree.  This is the directory
+#    that contains this "Makefile.in" and the "configure.in" script.
+#
+TOP = ../sqlite
+
+#### C Compiler and options for use in building executables that
+#    will run on the platform that is doing the build.
+#
+BCC = gcc -g -O2
+#BCC = /opt/ancic/bin/c89 -0
+
+#### If the target operating system supports the "usleep()" system
+#    call, then define the HAVE_USLEEP macro for all C modules.
+#
+#USLEEP = 
+USLEEP = -DHAVE_USLEEP=1
+
+#### If you want the SQLite library to be safe for use within a 
+#    multi-threaded program, then define the following macro
+#    appropriately:
+#
+#THREADSAFE = -DTHREADSAFE=1
+THREADSAFE = -DTHREADSAFE=0
+
+#### Specify any extra linker options needed to make the library
+#    thread safe
+#
+#THREADLIB = -lpthread
+THREADLIB = 
+
+#### Specify any extra libraries needed to access required functions.
+#
+#TLIBS = -lrt    # fdatasync on Solaris 8
+TLIBS = 
+
+#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
+#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
+#    malloc()s and free()s in order to track down memory leaks.
+#    
+#    SQLite uses some expensive assert() statements in the inner loop.
+#    You can make the library go almost twice as fast if you compile
+#    with -DNDEBUG=1
+#
+#OPTS = -DSQLITE_DEBUG=2
+#OPTS = -DSQLITE_DEBUG=1
+#OPTS = 
+OPTS = -DNDEBUG=1
+OPTS += -DHAVE_FDATASYNC=1
+
+#### The suffix to add to executable files.  ".exe" for windows.
+#    Nothing for unix.
+#
+#EXE = .exe
+EXE =
+
+#### C Compile and options for use in building executables that 
+#    will run on the target platform.  This is usually the same
+#    as BCC, unless you are cross-compiling.
+#
+TCC = gcc -O6
+#TCC = gcc -g -O0 -Wall
+#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
+#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
+#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
+
+#### Tools used to build a static library.
+#
+AR = ar cr
+#AR = /opt/mingw/bin/i386-mingw32-ar cr
+RANLIB = ranlib
+#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
+
+MKSHLIB = gcc -shared
+SO = so
+SHPREFIX = lib
+# SO = dll
+# SHPREFIX =
+
+#### Extra compiler options needed for programs that use the TCL library.
+#
+#TCL_FLAGS =
+#TCL_FLAGS = -DSTATIC_BUILD=1
+TCL_FLAGS = -I/home/drh/tcltk/8.5linux
+#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
+#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
+
+#### Linker options needed to link against the TCL library.
+#
+#LIBTCL = -ltcl -lm -ldl
+LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
+#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
+#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
+
+#### Additional objects for SQLite library when TCL support is enabled.
+#TCLOBJ =
+TCLOBJ = tclsqlite.o
+
+#### Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS =
+#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
+
+#### Linker options needed by programs using readline() must link against.
+#
+LIBREADLINE =
+#LIBREADLINE = -static -lreadline -ltermcap
+
+#### Which "awk" program provides nawk compatibilty
+#
+# NAWK = nawk
+NAWK = awk
+
+# You should not have to change anything below this line
+###############################################################################
+include $(TOP)/main.mk

+ 1005 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.msc

@@ -0,0 +1,1005 @@
+#
+# nmake Makefile for SQLite
+#
+
+# The toplevel directory of the source tree.  This is the directory
+# that contains this "Makefile.msc".
+#
+TOP = .
+
+# Set this non-0 to create and use the SQLite amalgamation file.
+#
+USE_AMALGAMATION = 1
+
+# Set this non-0 to use the International Components for Unicode (ICU).
+#
+USE_ICU = 0
+
+# Set this to non-0 to create and use PDBs.
+#
+SYMBOLS = 1
+
+# Set this to one of the following values to enable various debugging
+# features.  Each level includes the debugging options from the previous
+# levels.  Currently, the recognized values for DEBUG are:
+#
+# 0 == NDEBUG: Disables assert() and other runtime diagnostics.
+# 1 == Disables NDEBUG and all optimizations and then enables PDBs.
+# 2 == SQLITE_DEBUG: Enables various diagnostics messages and code.
+# 3 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
+# 4 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
+# 5 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
+#
+DEBUG = 0
+
+# Version numbers and release number for the SQLite being compiled.
+#
+VERSION = 3.7
+VERSION_NUMBER = 3007009
+RELEASE = 3.7.9
+
+# C Compiler and options for use in building executables that
+# will run on the platform that is doing the build.
+#
+BCC = cl.exe
+
+# C Compile and options for use in building executables that
+# will run on the target platform.  (BCC and TCC are usually the
+# same unless your are cross-compiling.)
+#
+TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
+
+# The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in 
+# any extension header files by default.  For non-amalgamation
+# builds, we need to make sure the compiler can find these.
+#
+!IF $(USE_AMALGAMATION)==0
+TCC = $(TCC) -I$(TOP)\ext\fts3
+TCC = $(TCC) -I$(TOP)\ext\rtree
+!ENDIF
+
+# Define -DNDEBUG to compile without debugging (i.e., for production usage)
+# Omitting the define will cause extra debugging code to be inserted and
+# includes extra comments when "EXPLAIN stmt" is used.
+#
+!IF $(DEBUG)==0
+TCC = $(TCC) -DNDEBUG
+!ENDIF
+
+!IF $(DEBUG)>1
+TCC = $(TCC) -DSQLITE_DEBUG
+!ENDIF
+
+!IF $(DEBUG)>3
+TCC = $(TCC) -DSQLITE_DEBUG_OS_TRACE=1
+!ENDIF
+
+!IF $(DEBUG)>4
+TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE
+!ENDIF
+
+#
+# Prevent warnings about "insecure" runtime library functions being used.
+#
+TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
+
+#
+# Use native Win32 heap instead of malloc/free?
+#
+# TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
+
+#
+# Validate the heap on every call into the native Win32 heap subsystem?
+#
+!IF $(DEBUG)>2
+TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
+!ENDIF
+
+# The locations of the Tcl header and library files.  Also, the library that
+# non-stubs enabled programs using Tcl must link against.  These variables
+# (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
+# prior to running nmake in order to match the actual installed location and
+# version on this machine.
+#
+!if "$(TCLINCDIR)" == ""
+TCLINCDIR = c:\tcl\include
+!endif
+
+!if "$(TCLLIBDIR)" == ""
+TCLLIBDIR = c:\tcl\lib
+!endif
+
+!if "$(LIBTCL)" == ""
+LIBTCL = tcl85.lib
+!endif
+
+# The locations of the ICU header and library files.  These variables
+# (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
+# prior to running nmake in order to match the actual installed location on
+# this machine.
+#
+!if "$(ICUINCDIR)" == ""
+ICUINCDIR = c:\icu\include
+!endif
+
+!if "$(ICULIBDIR)" == ""
+ICULIBDIR = c:\icu\lib
+!endif
+
+!if "$(LIBICU)" == ""
+LIBICU = icuuc.lib icuin.lib
+!endif
+
+# This is the command to use for tclsh - normally just "tclsh", but we may
+# know the specific version we want to use.  This variable (TCLSH_CMD) may be
+# overridden via the environment prior to running nmake in order to select a
+# specific Tcl shell to use.
+#
+!if "$(TCLSH_CMD)" == ""
+TCLSH_CMD = tclsh85
+!endif
+
+# Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS = -DHAVE_READLINE=0
+
+# The library that programs using readline() must link against.
+#
+LIBREADLINE =
+
+# Should the database engine be compiled threadsafe
+#
+TCC = $(TCC) -DSQLITE_THREADSAFE=1
+
+# Do threads override each others locks by default (1), or do we test (-1)
+#
+TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
+
+# Any target libraries which libsqlite must be linked against
+#
+!if "$(TLIBS)" == ""
+TLIBS =
+!endif
+
+# Flags controlling use of the in memory btree implementation
+#
+# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
+# default to file, 2 to default to memory, and 3 to force temporary
+# tables to always be in memory.
+#
+TCC = $(TCC) -DSQLITE_TEMP_STORE=1
+
+# Enable/disable loadable extensions, and other optional features
+# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
+# The same set of OMIT and ENABLE flags should be passed to the
+# LEMON parser generator and the mkkeywordhash tool as well.
+
+# BEGIN standard options
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
+# END standard options
+
+# BEGIN required Windows option
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100
+# END required Windows option
+
+TCC = $(TCC) $(OPT_FEATURE_FLAGS)
+
+# Add in any optional parameters specified on the make commane line
+# ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
+TCC = $(TCC) $(OPTS)
+
+# If symbols are enabled, enable PDBs.
+# If debugging is enabled, disable all optimizations and enable PDBs.
+!IF $(DEBUG)>0
+TCC = $(TCC) -Od -D_DEBUG
+!ELSE
+TCC = $(TCC) -O2
+!ENDIF
+
+!IF $(DEBUG)>0 || $(SYMBOLS)!=0
+TCC = $(TCC) -Zi
+!ENDIF
+
+# If ICU support is enabled, add the compiler options for it.
+!IF $(USE_ICU)!=0
+TCC = $(TCC) -DSQLITE_ENABLE_ICU=1
+TCC = $(TCC) -I$(TOP)\ext\icu
+TCC = $(TCC) -I$(ICUINCDIR)
+!ENDIF
+
+# libtool compile/link
+LTCOMPILE = $(TCC) -Fo$@
+LTLIB = lib.exe
+LTLINK = $(TCC) -Fe$@
+
+# If a platform was set, force the linker to target that.
+# Note that the vcvars*.bat family of batch files typically
+# set this for you.  Otherwise, the linker will attempt
+# to deduce the binary type based on the object files.
+!IF "$(PLATFORM)"!=""
+LTLINKOPTS = /MACHINE:$(PLATFORM)
+LTLIBOPTS = /MACHINE:$(PLATFORM)
+!ENDIF
+
+# If debugging is enabled, enable PDBs.
+!IF $(DEBUG)>0 || $(SYMBOLS)!=0
+LTLINKOPTS = $(LTLINKOPTS) /DEBUG
+!ENDIF
+
+# Start with the Tcl related linker options.
+LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
+LTLIBS = $(LIBTCL)
+
+# If ICU support is enabled, add the linker options for it.
+!IF $(USE_ICU)!=0
+LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
+LTLIBS = $(LTLIBS) $(LIBICU)
+!ENDIF
+
+# nawk compatible awk.
+NAWK = gawk.exe
+
+# You should not have to change anything below this line
+###############################################################################
+
+# Object files for the SQLite library (non-amalgamation).
+#
+LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
+         backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
+         callback.lo complete.lo ctime.lo date.lo delete.lo \
+         expr.lo fault.lo fkey.lo \
+         fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \
+         fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \
+         func.lo global.lo hash.lo \
+         icu.lo insert.lo journal.lo legacy.lo loadext.lo \
+         main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
+         memjournal.lo \
+         mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
+         notify.lo opcodes.lo os.lo os_os2.lo os_unix.lo os_win.lo \
+         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
+         random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
+         table.lo tokenize.lo trigger.lo \
+         update.lo util.lo vacuum.lo \
+         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
+         vdbetrace.lo wal.lo walker.lo where.lo utf.lo vtab.lo
+
+# Object files for the amalgamation.
+#
+LIBOBJS1 = sqlite3.lo
+
+# Determine the real value of LIBOBJ based on the 'configure' script
+#
+!IF $(USE_AMALGAMATION)==0
+LIBOBJ = $(LIBOBJS0)
+!ELSE
+LIBOBJ = $(LIBOBJS1)
+!ENDIF
+
+# All of the source code files.
+#
+SRC = \
+  $(TOP)\src\alter.c \
+  $(TOP)\src\analyze.c \
+  $(TOP)\src\attach.c \
+  $(TOP)\src\auth.c \
+  $(TOP)\src\backup.c \
+  $(TOP)\src\bitvec.c \
+  $(TOP)\src\btmutex.c \
+  $(TOP)\src\btree.c \
+  $(TOP)\src\btree.h \
+  $(TOP)\src\btreeInt.h \
+  $(TOP)\src\build.c \
+  $(TOP)\src\callback.c \
+  $(TOP)\src\complete.c \
+  $(TOP)\src\ctime.c \
+  $(TOP)\src\date.c \
+  $(TOP)\src\delete.c \
+  $(TOP)\src\expr.c \
+  $(TOP)\src\fault.c \
+  $(TOP)\src\fkey.c \
+  $(TOP)\src\func.c \
+  $(TOP)\src\global.c \
+  $(TOP)\src\hash.c \
+  $(TOP)\src\hash.h \
+  $(TOP)\src\hwtime.h \
+  $(TOP)\src\insert.c \
+  $(TOP)\src\journal.c \
+  $(TOP)\src\legacy.c \
+  $(TOP)\src\loadext.c \
+  $(TOP)\src\main.c \
+  $(TOP)\src\malloc.c \
+  $(TOP)\src\mem0.c \
+  $(TOP)\src\mem1.c \
+  $(TOP)\src\mem2.c \
+  $(TOP)\src\mem3.c \
+  $(TOP)\src\mem5.c \
+  $(TOP)\src\memjournal.c \
+  $(TOP)\src\mutex.c \
+  $(TOP)\src\mutex.h \
+  $(TOP)\src\mutex_noop.c \
+  $(TOP)\src\mutex_os2.c \
+  $(TOP)\src\mutex_unix.c \
+  $(TOP)\src\mutex_w32.c \
+  $(TOP)\src\notify.c \
+  $(TOP)\src\os.c \
+  $(TOP)\src\os.h \
+  $(TOP)\src\os_common.h \
+  $(TOP)\src\os_os2.c \
+  $(TOP)\src\os_unix.c \
+  $(TOP)\src\os_win.c \
+  $(TOP)\src\pager.c \
+  $(TOP)\src\pager.h \
+  $(TOP)\src\parse.y \
+  $(TOP)\src\pcache.c \
+  $(TOP)\src\pcache.h \
+  $(TOP)\src\pcache1.c \
+  $(TOP)\src\pragma.c \
+  $(TOP)\src\prepare.c \
+  $(TOP)\src\printf.c \
+  $(TOP)\src\random.c \
+  $(TOP)\src\resolve.c \
+  $(TOP)\src\rowset.c \
+  $(TOP)\src\select.c \
+  $(TOP)\src\status.c \
+  $(TOP)\src\shell.c \
+  $(TOP)\src\sqlite.h.in \
+  $(TOP)\src\sqlite3ext.h \
+  $(TOP)\src\sqliteInt.h \
+  $(TOP)\src\sqliteLimit.h \
+  $(TOP)\src\table.c \
+  $(TOP)\src\tclsqlite.c \
+  $(TOP)\src\tokenize.c \
+  $(TOP)\src\trigger.c \
+  $(TOP)\src\utf.c \
+  $(TOP)\src\update.c \
+  $(TOP)\src\util.c \
+  $(TOP)\src\vacuum.c \
+  $(TOP)\src\vdbe.c \
+  $(TOP)\src\vdbe.h \
+  $(TOP)\src\vdbeapi.c \
+  $(TOP)\src\vdbeaux.c \
+  $(TOP)\src\vdbeblob.c \
+  $(TOP)\src\vdbemem.c \
+  $(TOP)\src\vdbesort.c \
+  $(TOP)\src\vdbetrace.c \
+  $(TOP)\src\vdbeInt.h \
+  $(TOP)\src\vtab.c \
+  $(TOP)\src\wal.c \
+  $(TOP)\src\wal.h \
+  $(TOP)\src\walker.c \
+  $(TOP)\src\where.c
+
+# Source code for extensions
+#
+SRC = $(SRC) \
+  $(TOP)\ext\fts1\fts1.c \
+  $(TOP)\ext\fts1\fts1.h \
+  $(TOP)\ext\fts1\fts1_hash.c \
+  $(TOP)\ext\fts1\fts1_hash.h \
+  $(TOP)\ext\fts1\fts1_porter.c \
+  $(TOP)\ext\fts1\fts1_tokenizer.h \
+  $(TOP)\ext\fts1\fts1_tokenizer1.c
+SRC = $(SRC) \
+  $(TOP)\ext\fts2\fts2.c \
+  $(TOP)\ext\fts2\fts2.h \
+  $(TOP)\ext\fts2\fts2_hash.c \
+  $(TOP)\ext\fts2\fts2_hash.h \
+  $(TOP)\ext\fts2\fts2_icu.c \
+  $(TOP)\ext\fts2\fts2_porter.c \
+  $(TOP)\ext\fts2\fts2_tokenizer.h \
+  $(TOP)\ext\fts2\fts2_tokenizer.c \
+  $(TOP)\ext\fts2\fts2_tokenizer1.c
+SRC = $(SRC) \
+  $(TOP)\ext\fts3\fts3.c \
+  $(TOP)\ext\fts3\fts3.h \
+  $(TOP)\ext\fts3\fts3Int.h \
+  $(TOP)\ext\fts3\fts3_aux.c \
+  $(TOP)\ext\fts3\fts3_expr.c \
+  $(TOP)\ext\fts3\fts3_hash.c \
+  $(TOP)\ext\fts3\fts3_hash.h \
+  $(TOP)\ext\fts3\fts3_icu.c \
+  $(TOP)\ext\fts3\fts3_porter.c \
+  $(TOP)\ext\fts3\fts3_snippet.c \
+  $(TOP)\ext\fts3\fts3_tokenizer.h \
+  $(TOP)\ext\fts3\fts3_tokenizer.c \
+  $(TOP)\ext\fts3\fts3_tokenizer1.c \
+  $(TOP)\ext\fts3\fts3_write.c
+SRC = $(SRC) \
+  $(TOP)\ext\icu\sqliteicu.h \
+  $(TOP)\ext\icu\icu.c
+SRC = $(SRC) \
+  $(TOP)\ext\rtree\rtree.h \
+  $(TOP)\ext\rtree\rtree.c
+
+
+# Generated source code files
+#
+SRC = $(SRC) \
+  keywordhash.h \
+  opcodes.c \
+  opcodes.h \
+  parse.c \
+  parse.h \
+  sqlite3.h
+
+# Source code to the test files.
+#
+TESTSRC = \
+  $(TOP)\src\test1.c \
+  $(TOP)\src\test2.c \
+  $(TOP)\src\test3.c \
+  $(TOP)\src\test4.c \
+  $(TOP)\src\test5.c \
+  $(TOP)\src\test6.c \
+  $(TOP)\src\test7.c \
+  $(TOP)\src\test8.c \
+  $(TOP)\src\test9.c \
+  $(TOP)\src\test_autoext.c \
+  $(TOP)\src\test_async.c \
+  $(TOP)\src\test_backup.c \
+  $(TOP)\src\test_btree.c \
+  $(TOP)\src\test_config.c \
+  $(TOP)\src\test_demovfs.c \
+  $(TOP)\src\test_devsym.c \
+  $(TOP)\src\test_func.c \
+  $(TOP)\src\test_fuzzer.c \
+  $(TOP)\src\test_hexio.c \
+  $(TOP)\src\test_init.c \
+  $(TOP)\src\test_intarray.c \
+  $(TOP)\src\test_journal.c \
+  $(TOP)\src\test_malloc.c \
+  $(TOP)\src\test_multiplex.c \
+  $(TOP)\src\test_mutex.c \
+  $(TOP)\src\test_onefile.c \
+  $(TOP)\src\test_osinst.c \
+  $(TOP)\src\test_pcache.c \
+  $(TOP)\src\test_quota.c \
+  $(TOP)\src\test_rtree.c \
+  $(TOP)\src\test_schema.c \
+  $(TOP)\src\test_server.c \
+  $(TOP)\src\test_superlock.c \
+  $(TOP)\src\test_syscall.c \
+  $(TOP)\src\test_stat.c \
+  $(TOP)\src\test_tclvar.c \
+  $(TOP)\src\test_thread.c \
+  $(TOP)\src\test_vfs.c \
+  $(TOP)\src\test_wholenumber.c \
+  $(TOP)\src\test_wsd.c \
+  $(TOP)\ext\fts3\fts3_term.c \
+  $(TOP)\ext\fts3\fts3_test.c
+
+# Source code to the library files needed by the test fixture
+#
+TESTSRC2 = \
+  $(TOP)\src\attach.c \
+  $(TOP)\src\backup.c \
+  $(TOP)\src\bitvec.c \
+  $(TOP)\src\btree.c \
+  $(TOP)\src\build.c \
+  $(TOP)\src\ctime.c \
+  $(TOP)\src\date.c \
+  $(TOP)\src\expr.c \
+  $(TOP)\src\func.c \
+  $(TOP)\src\insert.c \
+  $(TOP)\src\wal.c \
+  $(TOP)\src\mem5.c \
+  $(TOP)\src\os.c \
+  $(TOP)\src\os_os2.c \
+  $(TOP)\src\os_unix.c \
+  $(TOP)\src\os_win.c \
+  $(TOP)\src\pager.c \
+  $(TOP)\src\pragma.c \
+  $(TOP)\src\prepare.c \
+  $(TOP)\src\printf.c \
+  $(TOP)\src\random.c \
+  $(TOP)\src\pcache.c \
+  $(TOP)\src\pcache1.c \
+  $(TOP)\src\select.c \
+  $(TOP)\src\tokenize.c \
+  $(TOP)\src\utf.c \
+  $(TOP)\src\util.c \
+  $(TOP)\src\vdbeapi.c \
+  $(TOP)\src\vdbeaux.c \
+  $(TOP)\src\vdbe.c \
+  $(TOP)\src\vdbemem.c \
+  $(TOP)\src\vdbesort.c \
+  $(TOP)\src\vdbetrace.c \
+  $(TOP)\src\where.c \
+  parse.c \
+  $(TOP)\ext\fts3\fts3.c \
+  $(TOP)\ext\fts3\fts3_aux.c \
+  $(TOP)\ext\fts3\fts3_expr.c \
+  $(TOP)\ext\fts3\fts3_tokenizer.c \
+  $(TOP)\ext\fts3\fts3_write.c \
+  $(TOP)\ext\async\sqlite3async.c
+
+# Header files used by all library source files.
+#
+HDR = \
+   $(TOP)\src\btree.h \
+   $(TOP)\src\btreeInt.h \
+   $(TOP)\src\hash.h \
+   $(TOP)\src\hwtime.h \
+   keywordhash.h \
+   $(TOP)\src\mutex.h \
+   opcodes.h \
+   $(TOP)\src\os.h \
+   $(TOP)\src\os_common.h \
+   $(TOP)\src\pager.h \
+   $(TOP)\src\pcache.h \
+   parse.h \
+   sqlite3.h \
+   $(TOP)\src\sqlite3ext.h \
+   $(TOP)\src\sqliteInt.h \
+   $(TOP)\src\sqliteLimit.h \
+   $(TOP)\src\vdbe.h \
+   $(TOP)\src\vdbeInt.h
+
+# Header files used by extensions
+#
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\fts1\fts1.h \
+  $(TOP)\ext\fts1\fts1_hash.h \
+  $(TOP)\ext\fts1\fts1_tokenizer.h
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\fts2\fts2.h \
+  $(TOP)\ext\fts2\fts2_hash.h \
+  $(TOP)\ext\fts2\fts2_tokenizer.h
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\fts3\fts3.h \
+  $(TOP)\ext\fts3\fts3Int.h \
+  $(TOP)\ext\fts3\fts3_hash.h \
+  $(TOP)\ext\fts3\fts3_tokenizer.h
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\rtree\rtree.h
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\icu\sqliteicu.h
+EXTHDR = $(EXTHDR) \
+  $(TOP)\ext\rtree\sqlite3rtree.h
+
+# This is the default Makefile target.  The objects listed here
+# are what get build when you type just "make" with no arguments.
+#
+all:	dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib
+
+libsqlite3.lib:	$(LIBOBJ)
+	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
+
+libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
+	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
+
+sqlite3.exe:	$(TOP)\src\shell.c libsqlite3.lib sqlite3.h
+	$(LTLINK) $(READLINE_FLAGS) \
+		$(TOP)\src\shell.c \
+		/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBREADLINE) $(LTLIBS) $(TLIBS)
+
+# This target creates a directory named "tsrc" and fills it with
+# copies of all of the C source code and header files needed to
+# build on the target system.  Some of the C source code and header
+# files are automatically generated.  This target takes care of
+# all that automatic generation.
+#
+.target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl
+	-rmdir /S/Q tsrc
+	-mkdir tsrc
+	for %i in ($(SRC)) do copy /Y %i tsrc
+	del /Q tsrc\sqlite.h.in tsrc\parse.y
+	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl < tsrc\vdbe.c > vdbe.new
+	move vdbe.new tsrc\vdbe.c
+	echo > .target_source
+
+sqlite3.c:	.target_source $(TOP)\tool\mksqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
+
+sqlite3-all.c:	sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
+	$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
+
+# Rule to build the amalgamation
+#
+sqlite3.lo:	sqlite3.c
+	$(LTCOMPILE) -c sqlite3.c
+
+# Rules to build the LEMON compiler generator
+#
+lempar.c:	$(TOP)\src\lempar.c
+	copy $(TOP)\src\lempar.c .
+
+lemon.exe:	$(TOP)\tool\lemon.c lempar.c
+	$(BCC) -Fe$@ $(TOP)\tool\lemon.c
+
+# Rules to build individual *.lo files from generated *.c files. This
+# applies to:
+#
+#     parse.lo
+#     opcodes.lo
+#
+parse.lo:	parse.c $(HDR)
+	$(LTCOMPILE) -c parse.c
+
+opcodes.lo:	opcodes.c
+	$(LTCOMPILE) -c opcodes.c
+
+# Rules to build individual *.lo files from files in the src directory.
+#
+alter.lo:	$(TOP)\src\alter.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\alter.c
+
+analyze.lo:	$(TOP)\src\analyze.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\analyze.c
+
+attach.lo:	$(TOP)\src\attach.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\attach.c
+
+auth.lo:	$(TOP)\src\auth.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\auth.c
+
+backup.lo:	$(TOP)\src\backup.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\backup.c
+
+bitvec.lo:	$(TOP)\src\bitvec.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\bitvec.c
+
+btmutex.lo:	$(TOP)\src\btmutex.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\btmutex.c
+
+btree.lo:	$(TOP)\src\btree.c $(HDR) $(TOP)\src\pager.h
+	$(LTCOMPILE) -c $(TOP)\src\btree.c
+
+build.lo:	$(TOP)\src\build.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\build.c
+
+callback.lo:	$(TOP)\src\callback.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\callback.c
+
+complete.lo:	$(TOP)\src\complete.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\complete.c
+
+ctime.lo:	$(TOP)\src\ctime.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\ctime.c
+
+date.lo:	$(TOP)\src\date.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\date.c
+
+delete.lo:	$(TOP)\src\delete.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\delete.c
+
+expr.lo:	$(TOP)\src\expr.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\expr.c
+
+fault.lo:	$(TOP)\src\fault.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\fault.c
+
+fkey.lo:	$(TOP)\src\fkey.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\fkey.c
+
+func.lo:	$(TOP)\src\func.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\func.c
+
+global.lo:	$(TOP)\src\global.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\global.c
+
+hash.lo:	$(TOP)\src\hash.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\hash.c
+
+insert.lo:	$(TOP)\src\insert.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\insert.c
+
+journal.lo:	$(TOP)\src\journal.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\journal.c
+
+legacy.lo:	$(TOP)\src\legacy.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\legacy.c
+
+loadext.lo:	$(TOP)\src\loadext.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\loadext.c
+
+main.lo:	$(TOP)\src\main.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\main.c
+
+malloc.lo:	$(TOP)\src\malloc.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\malloc.c
+
+mem0.lo:	$(TOP)\src\mem0.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mem0.c
+
+mem1.lo:	$(TOP)\src\mem1.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mem1.c
+
+mem2.lo:	$(TOP)\src\mem2.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mem2.c
+
+mem3.lo:	$(TOP)\src\mem3.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mem3.c
+
+mem5.lo:	$(TOP)\src\mem5.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mem5.c
+
+memjournal.lo:	$(TOP)\src\memjournal.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\memjournal.c
+
+mutex.lo:	$(TOP)\src\mutex.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mutex.c
+
+mutex_noop.lo:	$(TOP)\src\mutex_noop.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mutex_noop.c
+
+mutex_os2.lo:	$(TOP)\src\mutex_os2.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mutex_os2.c
+
+mutex_unix.lo:	$(TOP)\src\mutex_unix.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mutex_unix.c
+
+mutex_w32.lo:	$(TOP)\src\mutex_w32.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\mutex_w32.c
+
+notify.lo:	$(TOP)\src\notify.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\notify.c
+
+pager.lo:	$(TOP)\src\pager.c $(HDR) $(TOP)\src\pager.h
+	$(LTCOMPILE) -c $(TOP)\src\pager.c
+
+pcache.lo:	$(TOP)\src\pcache.c $(HDR) $(TOP)\src\pcache.h
+	$(LTCOMPILE) -c $(TOP)\src\pcache.c
+
+pcache1.lo:	$(TOP)\src\pcache1.c $(HDR) $(TOP)\src\pcache.h
+	$(LTCOMPILE) -c $(TOP)\src\pcache1.c
+
+os.lo:	$(TOP)\src\os.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\os.c
+
+os_unix.lo:	$(TOP)\src\os_unix.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\os_unix.c
+
+os_win.lo:	$(TOP)\src\os_win.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\os_win.c
+
+os_os2.lo:	$(TOP)\src\os_os2.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\os_os2.c
+
+pragma.lo:	$(TOP)\src\pragma.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\pragma.c
+
+prepare.lo:	$(TOP)\src\prepare.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\prepare.c
+
+printf.lo:	$(TOP)\src\printf.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\printf.c
+
+random.lo:	$(TOP)\src\random.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\random.c
+
+resolve.lo:	$(TOP)\src\resolve.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\resolve.c
+
+rowset.lo:	$(TOP)\src\rowset.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\rowset.c
+
+select.lo:	$(TOP)\src\select.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\select.c
+
+status.lo:	$(TOP)\src\status.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\status.c
+
+table.lo:	$(TOP)\src\table.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\table.c
+
+tokenize.lo:	$(TOP)\src\tokenize.c keywordhash.h $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\tokenize.c
+
+trigger.lo:	$(TOP)\src\trigger.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\trigger.c
+
+update.lo:	$(TOP)\src\update.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\update.c
+
+utf.lo:	$(TOP)\src\utf.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\utf.c
+
+util.lo:	$(TOP)\src\util.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\util.c
+
+vacuum.lo:	$(TOP)\src\vacuum.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vacuum.c
+
+vdbe.lo:	$(TOP)\src\vdbe.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbe.c
+
+vdbeapi.lo:	$(TOP)\src\vdbeapi.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbeapi.c
+
+vdbeaux.lo:	$(TOP)\src\vdbeaux.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbeaux.c
+
+vdbeblob.lo:	$(TOP)\src\vdbeblob.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbeblob.c
+
+vdbemem.lo:	$(TOP)\src\vdbemem.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbemem.c
+
+vdbesort.lo:	$(TOP)\src\vdbesort.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbesort.c
+
+vdbetrace.lo:	$(TOP)\src\vdbetrace.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vdbetrace.c
+
+vtab.lo:	$(TOP)\src\vtab.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\vtab.c
+
+wal.lo:	$(TOP)\src\wal.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\wal.c
+
+walker.lo:	$(TOP)\src\walker.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\walker.c
+
+where.lo:	$(TOP)\src\where.c $(HDR)
+	$(LTCOMPILE) -c $(TOP)\src\where.c
+
+tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
+
+tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR)
+	$(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
+
+tclsqlite3.exe:	tclsqlite-shell.lo libsqlite3.lib
+	$(LTLINK) tclsqlite-shell.lo \
+		/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LTLIBS) $(TLIBS)
+
+# Rules to build opcodes.c and opcodes.h
+#
+opcodes.c:	opcodes.h $(TOP)\mkopcodec.awk
+	$(NAWK) -f $(TOP)\mkopcodec.awk opcodes.h > opcodes.c
+
+opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\mkopcodeh.awk
+	type parse.h $(TOP)\src\vdbe.c | $(NAWK) -f $(TOP)\mkopcodeh.awk > opcodes.h
+
+# Rules to build parse.c and parse.h - the outputs of lemon.
+#
+parse.h:	parse.c
+
+parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
+	del /Q parse.y parse.h parse.h.temp
+	copy $(TOP)\src\parse.y .
+	.\lemon.exe $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
+	move parse.h parse.h.temp
+	$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
+
+sqlite3.h:	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
+	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP) > sqlite3.h
+
+mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
+	$(BCC) -Femkkeywordhash.exe $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c
+
+keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
+	.\mkkeywordhash.exe > keywordhash.h
+
+
+
+# Rules to build the extension objects.
+#
+icu.lo:	$(TOP)\ext\icu\icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\icu\icu.c
+
+fts2.lo:	$(TOP)\ext\fts2\fts2.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2.c
+
+fts2_hash.lo:	$(TOP)\ext\fts2\fts2_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2_hash.c
+
+fts2_icu.lo:	$(TOP)\ext\fts2\fts2_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2_icu.c
+
+fts2_porter.lo:	$(TOP)\ext\fts2\fts2_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2_porter.c
+
+fts2_tokenizer.lo:	$(TOP)\ext\fts2\fts2_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2_tokenizer.c
+
+fts2_tokenizer1.lo:	$(TOP)\ext\fts2\fts2_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts2\fts2_tokenizer1.c
+
+fts3.lo:	$(TOP)\ext\fts3\fts3.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3.c
+
+fts3_aux.lo:	$(TOP)\ext\fts3\fts3_aux.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_aux.c
+
+fts3_expr.lo:	$(TOP)\ext\fts3\fts3_expr.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_expr.c
+
+fts3_hash.lo:	$(TOP)\ext\fts3\fts3_hash.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_hash.c
+
+fts3_icu.lo:	$(TOP)\ext\fts3\fts3_icu.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_icu.c
+
+fts3_snippet.lo:	$(TOP)\ext\fts3\fts3_snippet.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_snippet.c
+
+fts3_porter.lo:	$(TOP)\ext\fts3\fts3_porter.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_porter.c
+
+fts3_tokenizer.lo:	$(TOP)\ext\fts3\fts3_tokenizer.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer.c
+
+fts3_tokenizer1.lo:	$(TOP)\ext\fts3\fts3_tokenizer1.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer1.c
+
+fts3_write.lo:	$(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c
+
+rtree.lo:	$(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
+	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
+
+
+# Rules to build the 'testfixture' application.
+#
+# If using the amalgamation, use sqlite3.c directly to build the test
+# fixture.  Otherwise link against libsqlite3.lib.  (This distinction is
+# necessary because the test fixture requires non-API symbols which are
+# hidden when the library is built via the amalgamation).
+#
+TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
+TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
+
+TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.lib
+TESTFIXTURE_SRC1 = sqlite3.c
+!IF $(USE_AMALGAMATION)==0
+TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
+!ELSE
+TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
+!ENDIF
+
+testfixture.exe:	$(TESTFIXTURE_SRC) $(HDR)
+	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
+		-DBUILD_sqlite -I$(TCLINCDIR) \
+		$(TESTFIXTURE_SRC) \
+		/link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS)
+
+fulltest:	testfixture.exe sqlite3.exe
+	.\testfixture.exe $(TOP)\test\all.test
+
+soaktest:	testfixture.exe sqlite3.exe
+	.\testfixture.exe $(TOP)\test\all.test -soak=1
+
+test:	testfixture.exe sqlite3.exe
+	.\testfixture.exe $(TOP)\test\veryquick.test
+
+sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
+	copy sqlite3.c + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@
+	echo static const char *tclsh_main_loop(void){ >> $@
+	echo static const char *zMainloop = >> $@
+	$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
+	echo ; return zMainloop; } >> $@
+
+sqlite3_analyzer.exe:	sqlite3_analyzer.c
+	$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
+		/link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS)
+
+clean:
+	del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
+	del /Q sqlite3.h opcodes.c opcodes.h
+	del /Q lemon.exe lempar.c parse.*
+	del /Q mkkeywordhash.exe keywordhash.h
+	-rmdir /Q/S tsrc
+	del /Q .target_source
+	del /Q tclsqlite3.exe
+	del /Q testfixture.exe testfixture.exp test.db
+	del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
+	del /Q sqlite3.c
+	del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
+
+#
+# Windows section
+#
+dll: sqlite3.dll
+
+sqlite3.def: libsqlite3.lib
+	echo EXPORTS > sqlite3.def
+	dumpbin /all libsqlite3.lib \
+		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
+		| sort >> sqlite3.def
+
+sqlite3.dll: $(LIBOBJ) sqlite3.def
+	link $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LTLIBS) $(TLIBS)

+ 663 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/Makefile.vxworks

@@ -0,0 +1,663 @@
+#!/usr/make
+#
+# Makefile for SQLITE on VxWorks
+
+ifeq ($(FORCPU),)
+  FORCPU = SH32gnule
+endif
+
+TOOL_FAMILY = gnu
+
+include $(WIND_USR)/tool/gnu/make.$(FORCPU)
+
+#### The toplevel directory of the source tree.  This is the directory
+#    that contains this "Makefile.in" and the "configure.in" script.
+#
+TOP = .
+
+#### C Compiler and options for use in building executables that
+#    will run on the platform that is doing the build.
+#
+BCC = gcc -g -O2
+#BCC = /opt/ancic/bin/c89 -0
+
+#### If the target operating system supports the "usleep()" system
+#    call, then define the HAVE_USLEEP macro for all C modules.
+#
+USLEEP = 
+#USLEEP = -DHAVE_USLEEP=1
+
+#### If you want the SQLite library to be safe for use within a 
+#    multi-threaded program, then define the following macro
+#    appropriately:
+#
+THREADSAFE = -DSQLITE_THREADSAFE=1
+#THREADSAFE = -DSQLITE_THREADSAFE=0
+
+#### Specify any extra linker options needed to make the library
+#    thread safe
+#
+#THREADLIB = -lpthread
+THREADLIB = 
+
+#### Specify any extra libraries needed to access required functions.
+#
+ifeq ($(CPU),SH32) 
+  # for SH4 shared library
+  TLIBS_SHARED += -L$(WIND_USR)/lib/sh/SH32/commonle/PIC
+else 
+  # for all other CPUs shared library
+  TLIBS_SHARED += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
+endif
+# for static library
+TLIBS += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
+
+#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
+#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
+#    malloc()s and free()s in order to track down memory leaks.
+#    
+#    SQLite uses some expensive assert() statements in the inner loop.
+#    You can make the library go almost twice as fast if you compile
+#    with -DNDEBUG=1
+#
+#OPTS = -DSQLITE_DEBUG=2
+#OPTS = -DSQLITE_DEBUG=1
+#OPTS = 
+OPTS = -DNDEBUG=1 -DSQLITE_OS_UNIX=1 $(THREADSAFE)
+OPTS += -DSQLITE_OMIT_LOAD_EXTENSION=1
+OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=1
+OPTS += -DSQLITE_THREAD_OVERRIDE_LOCK=0
+OPTS += -DSQLITE_ENABLE_COLUMN_METADATA=1
+OPTS += -DHAVE_FDATASYNC=1
+
+#### The suffix to add to executable files.  ".exe" for windows.
+#    Nothing for unix.
+#
+EXE = .vxe
+#EXE =
+
+#### C Compile and options for use in building executables that 
+#    will run on the target platform.  This is usually the same
+#    as BCC, unless you are cross-compiling.
+#
+#TCC = gcc -O6
+#TCC = gcc -g -O0 -Wall
+#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
+#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
+TCC = $(CC) $(DEFINE_CC) -O2 -g -mrtp $(CC_ARCH_SPEC) -D_REENTRANT=1 -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
+TCC += -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip
+#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
+
+#TCC_SHARED = $(TCC) -fPIC
+TCC_SHARED = $(TCC)
+
+#### Tools used to build a static library.
+#
+#ARX = ar cr
+#ARX = /opt/mingw/bin/i386-mingw32-ar cr
+AR += cr
+#RANLIB = ranlib
+#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
+
+#MKSHLIB = gcc -shared
+#SO = so
+#SHPREFIX = lib
+MKSHLIB = $(CC) $(DEFINE_CC) -mrtp -shared $(CC_ARCH_SPEC) -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
+SO = so
+SHPREFIX = lib
+
+#### Extra compiler options needed for programs that use the TCL library.
+#
+#TCL_FLAGS =
+#TCL_FLAGS = -DSTATIC_BUILD=1
+TCL_FLAGS = -I/home/drh/tcltk/8.5linux
+#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
+#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
+
+#### Linker options needed to link against the TCL library.
+#
+#LIBTCL = -ltcl -lm -ldl
+LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
+#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
+#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
+
+#### Additional objects for SQLite library when TCL support is enabled.
+TCLOBJ =
+#TCLOBJ = tclsqlite.o
+
+#### Compiler options needed for programs that use the readline() library.
+#
+READLINE_FLAGS =
+#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
+
+#### Linker options needed by programs using readline() must link against.
+#
+LIBREADLINE =
+#LIBREADLINE = -static -lreadline -ltermcap
+
+#### Which "awk" program provides nawk compatibilty
+#
+# NAWK = nawk
+NAWK = awk
+
+
+#### Pasted and adapted main.mk file
+###############################################################################
+# The following macros should be defined before this script is
+# invoked:
+#
+# TOP              The toplevel directory of the source tree.  This is the
+#                  directory that contains this "Makefile.in" and the
+#                  "configure.in" script.
+#
+# BCC              C Compiler and options for use in building executables that
+#                  will run on the platform that is doing the build.
+#
+# THREADLIB        Specify any extra linker options needed to make the library
+#                  thread safe
+#
+# OPTS             Extra compiler command-line options.
+#
+# EXE              The suffix to add to executable files.  ".exe" for windows
+#                  and "" for Unix.
+#
+# TCC              C Compiler and options for use in building executables that 
+#                  will run on the target platform.  This is usually the same
+#                  as BCC, unless you are cross-compiling.
+#
+# AR               Tools used to build a static library.
+# RANLIB
+#
+# TCL_FLAGS        Extra compiler options needed for programs that use the
+#                  TCL library.
+#
+# LIBTCL           Linker options needed to link against the TCL library.
+#
+# READLINE_FLAGS   Compiler options needed for programs that use the
+#                  readline() library.
+#
+# LIBREADLINE      Linker options needed by programs using readline() must
+#                  link against.
+#
+# NAWK             Nawk compatible awk program.  Older (obsolete?) solaris
+#                  systems need this to avoid using the original AT&T AWK.
+#
+# Once the macros above are defined, the rest of this make script will
+# build the SQLite library and testing tools.
+################################################################################
+
+# This is how we compile
+#
+TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
+TCCX_SHARED = $(TCC_SHARED) $(OPTS) -I. -I$(TOP)/src -I$(TOP) \
+	-I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 \
+	-I$(TOP)/ext/async
+
+# Object files for the SQLite library.
+#
+LIBOBJ+= alter.o analyze.o attach.o auth.o \
+         backup.o bitvec.o btmutex.o btree.o build.o \
+         callback.o complete.o date.o delete.o expr.o fault.o \
+         fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
+         fts3_tokenizer.o fts3_tokenizer1.o \
+         func.o global.o hash.o \
+         icu.o insert.o journal.o legacy.o loadext.o \
+         main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
+         memjournal.o \
+         mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
+         notify.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
+         pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
+         random.o resolve.o rowset.o rtree.o select.o status.o \
+         table.o tokenize.o trigger.o \
+         update.o util.o vacuum.o \
+         vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
+         walker.o where.o utf.o vtab.o
+
+
+
+# All of the source code files.
+#
+SRC = \
+  $(TOP)/src/alter.c \
+  $(TOP)/src/analyze.c \
+  $(TOP)/src/attach.c \
+  $(TOP)/src/auth.c \
+  $(TOP)/src/backup.c \
+  $(TOP)/src/bitvec.c \
+  $(TOP)/src/btmutex.c \
+  $(TOP)/src/btree.c \
+  $(TOP)/src/btree.h \
+  $(TOP)/src/btreeInt.h \
+  $(TOP)/src/build.c \
+  $(TOP)/src/callback.c \
+  $(TOP)/src/complete.c \
+  $(TOP)/src/ctime.c \
+  $(TOP)/src/date.c \
+  $(TOP)/src/delete.c \
+  $(TOP)/src/expr.c \
+  $(TOP)/src/fault.c \
+  $(TOP)/src/func.c \
+  $(TOP)/src/global.c \
+  $(TOP)/src/hash.c \
+  $(TOP)/src/hash.h \
+  $(TOP)/src/hwtime.h \
+  $(TOP)/src/insert.c \
+  $(TOP)/src/journal.c \
+  $(TOP)/src/legacy.c \
+  $(TOP)/src/loadext.c \
+  $(TOP)/src/main.c \
+  $(TOP)/src/malloc.c \
+  $(TOP)/src/mem0.c \
+  $(TOP)/src/mem1.c \
+  $(TOP)/src/mem2.c \
+  $(TOP)/src/mem3.c \
+  $(TOP)/src/mem5.c \
+  $(TOP)/src/memjournal.c \
+  $(TOP)/src/mutex.c \
+  $(TOP)/src/mutex.h \
+  $(TOP)/src/mutex_noop.c \
+  $(TOP)/src/mutex_os2.c \
+  $(TOP)/src/mutex_unix.c \
+  $(TOP)/src/mutex_w32.c \
+  $(TOP)/src/notify.c \
+  $(TOP)/src/os.c \
+  $(TOP)/src/os.h \
+  $(TOP)/src/os_common.h \
+  $(TOP)/src/os_os2.c \
+  $(TOP)/src/os_unix.c \
+  $(TOP)/src/os_win.c \
+  $(TOP)/src/pager.c \
+  $(TOP)/src/pager.h \
+  $(TOP)/src/parse.y \
+  $(TOP)/src/pcache.c \
+  $(TOP)/src/pcache.h \
+  $(TOP)/src/pcache1.c \
+  $(TOP)/src/pragma.c \
+  $(TOP)/src/prepare.c \
+  $(TOP)/src/printf.c \
+  $(TOP)/src/random.c \
+  $(TOP)/src/resolve.c \
+  $(TOP)/src/rowset.c \
+  $(TOP)/src/select.c \
+  $(TOP)/src/status.c \
+  $(TOP)/src/shell.c \
+  $(TOP)/src/sqlite.h.in \
+  $(TOP)/src/sqlite3ext.h \
+  $(TOP)/src/sqliteInt.h \
+  $(TOP)/src/sqliteLimit.h \
+  $(TOP)/src/table.c \
+  $(TOP)/src/tclsqlite.c \
+  $(TOP)/src/tokenize.c \
+  $(TOP)/src/trigger.c \
+  $(TOP)/src/utf.c \
+  $(TOP)/src/update.c \
+  $(TOP)/src/util.c \
+  $(TOP)/src/vacuum.c \
+  $(TOP)/src/vdbe.c \
+  $(TOP)/src/vdbe.h \
+  $(TOP)/src/vdbeapi.c \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbeblob.c \
+  $(TOP)/src/vdbemem.c \
+  $(TOP)/src/vdbeInt.h \
+  $(TOP)/src/vtab.c \
+  $(TOP)/src/walker.c \
+  $(TOP)/src/where.c
+
+# Source code for extensions
+#
+SRC += \
+  $(TOP)/ext/fts1/fts1.c \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.c \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_porter.c \
+  $(TOP)/ext/fts1/fts1_tokenizer.h \
+  $(TOP)/ext/fts1/fts1_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts2/fts2.c \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.c \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_icu.c \
+  $(TOP)/ext/fts2/fts2_porter.c \
+  $(TOP)/ext/fts2/fts2_tokenizer.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.c \
+  $(TOP)/ext/fts2/fts2_tokenizer1.c
+SRC += \
+  $(TOP)/ext/fts3/fts3.c \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3_expr.c \
+  $(TOP)/ext/fts3/fts3_expr.h \
+  $(TOP)/ext/fts3/fts3_hash.c \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_icu.c \
+  $(TOP)/ext/fts3/fts3_porter.c \
+  $(TOP)/ext/fts3/fts3_tokenizer.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.c \
+  $(TOP)/ext/fts3/fts3_tokenizer1.c
+SRC += \
+  $(TOP)/ext/icu/sqliteicu.h \
+  $(TOP)/ext/icu/icu.c 
+SRC += \
+  $(TOP)/ext/rtree/rtree.h \
+  $(TOP)/ext/rtree/rtree.c
+
+
+# Generated source code files
+#
+SRC += \
+  keywordhash.h \
+  opcodes.c \
+  opcodes.h \
+  parse.c \
+  parse.h \
+  sqlite3.h
+
+
+# Source code to the test files.
+#
+TESTSRC = \
+  $(TOP)/src/test1.c \
+  $(TOP)/src/test2.c \
+  $(TOP)/src/test3.c \
+  $(TOP)/src/test4.c \
+  $(TOP)/src/test5.c \
+  $(TOP)/src/test6.c \
+  $(TOP)/src/test7.c \
+  $(TOP)/src/test8.c \
+  $(TOP)/src/test9.c \
+  $(TOP)/src/test_autoext.c \
+  $(TOP)/src/test_async.c \
+  $(TOP)/src/test_backup.c \
+  $(TOP)/src/test_btree.c \
+  $(TOP)/src/test_config.c \
+  $(TOP)/src/test_devsym.c \
+  $(TOP)/src/test_func.c \
+  $(TOP)/src/test_hexio.c \
+  $(TOP)/src/test_journal.c \
+  $(TOP)/src/test_malloc.c \
+  $(TOP)/src/test_md5.c \
+  $(TOP)/src/test_mutex.c \
+  $(TOP)/src/test_onefile.c \
+  $(TOP)/src/test_osinst.c \
+  $(TOP)/src/test_pcache.c \
+  $(TOP)/src/test_schema.c \
+  $(TOP)/src/test_server.c \
+  $(TOP)/src/test_tclvar.c \
+  $(TOP)/src/test_thread.c \
+  $(TOP)/src/test_vfs.c \
+  $(TOP)/src/test_wsd.c \
+
+#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
+#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
+
+TESTSRC2 = \
+  $(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c                   \
+  $(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c                      \
+  $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c      \
+  $(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c                 \
+  $(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c                  \
+  $(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c                  \
+  $(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c               \
+  $(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c            \
+  $(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c                           \
+  $(TOP)/ext/fts3/fts3_tokenizer.c                                             \
+  $(TOP)/ext/async/sqlite3async.c
+
+# Header files used by all library source files.
+#
+HDR = \
+   $(TOP)/src/btree.h \
+   $(TOP)/src/btreeInt.h \
+   $(TOP)/src/hash.h \
+   $(TOP)/src/hwtime.h \
+   keywordhash.h \
+   $(TOP)/src/mutex.h \
+   opcodes.h \
+   $(TOP)/src/os.h \
+   $(TOP)/src/os_common.h \
+   $(TOP)/src/pager.h \
+   $(TOP)/src/pcache.h \
+   parse.h  \
+   sqlite3.h  \
+   $(TOP)/src/sqlite3ext.h \
+   $(TOP)/src/sqliteInt.h  \
+   $(TOP)/src/sqliteLimit.h \
+   $(TOP)/src/vdbe.h \
+   $(TOP)/src/vdbeInt.h
+
+# Header files used by extensions
+#
+EXTHDR += \
+  $(TOP)/ext/fts1/fts1.h \
+  $(TOP)/ext/fts1/fts1_hash.h \
+  $(TOP)/ext/fts1/fts1_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts2/fts2.h \
+  $(TOP)/ext/fts2/fts2_hash.h \
+  $(TOP)/ext/fts2/fts2_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/fts3/fts3.h \
+  $(TOP)/ext/fts3/fts3_expr.h \
+  $(TOP)/ext/fts3/fts3_hash.h \
+  $(TOP)/ext/fts3/fts3_tokenizer.h
+EXTHDR += \
+  $(TOP)/ext/rtree/rtree.h
+EXTHDR += \
+  $(TOP)/ext/icu/sqliteicu.h
+
+# This is the default Makefile target.  The objects listed here
+# are what get build when you type just "make" with no arguments.
+#
+all:	sqlite3.h libsqlite3.a sqlite3$(EXE)
+
+libsqlite3.a:	$(LIBOBJ)
+	$(AR) libsqlite3.a $(LIBOBJ)
+	$(RANLIB) libsqlite3.a
+
+$(SHPREFIX)sqlite3.$(SO):	$(LIBOBJ)
+	$(MKSHLIB) -o $(SHPREFIX)sqlite3.$(SO) $(LIBOBJ) $(TLIBS_SHARED)
+
+sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
+	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)      \
+		$(TOP)/src/shell.c                      \
+		$(LIBREADLINE) $(TLIBS) $(THREADLIB) -L. -lsqlite3
+
+# This target creates a directory named "tsrc" and fills it with
+# copies of all of the C source code and header files needed to
+# build on the target system.  Some of the C source code and header
+# files are automatically generated.  This target takes care of
+# all that automatic generation.
+#
+target_source:	$(SRC)
+	rm -rf tsrc
+	mkdir tsrc
+	cp -f $(SRC) tsrc
+	rm tsrc/sqlite.h.in tsrc/parse.y
+	touch target_source
+
+sqlite3.c:	target_source $(TOP)/tool/mksqlite3c.tcl
+	tclsh $(TOP)/tool/mksqlite3c.tcl
+	cp sqlite3.c tclsqlite3.c
+	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
+
+fts2amal.c:	target_source $(TOP)/ext/fts2/mkfts2amal.tcl
+	tclsh $(TOP)/ext/fts2/mkfts2amal.tcl
+
+fts3amal.c:	target_source $(TOP)/ext/fts3/mkfts3amal.tcl
+	tclsh $(TOP)/ext/fts3/mkfts3amal.tcl
+
+# Rules to build the LEMON compiler generator
+#
+lemon:	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
+	$(BCC) -o lemon $(TOP)/tool/lemon.c
+	cp $(TOP)/src/lempar.c .
+
+# Rules to build individual *.o files from generated *.c files. This
+# applies to:
+#
+#     parse.o
+#     opcodes.o
+#
+%.o: %.c $(HDR)
+	$(TCCX_SHARED) -c $<
+
+# Rules to build individual *.o files from files in the src directory.
+#
+%.o: $(TOP)/src/%.c $(HDR)
+	$(TCCX_SHARED) -c $<
+
+tclsqlite.o:	$(TOP)/src/tclsqlite.c $(HDR)
+	$(TCCX_SHARED) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
+
+
+
+# Rules to build opcodes.c and opcodes.h
+#
+opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
+	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
+
+opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
+	cat parse.h $(TOP)/src/vdbe.c | \
+		$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
+
+# Rules to build parse.c and parse.h - the outputs of lemon.
+#
+parse.h:	parse.c
+
+parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
+	cp $(TOP)/src/parse.y .
+	rm -f parse.h
+	./lemon $(OPTS) parse.y
+	mv parse.h parse.h.temp
+	awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
+
+sqlite3.h:	$(TOP)/src/sqlite.h.in 
+	sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
+	    -e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
+                 $(TOP)/src/sqlite.h.in >sqlite3.h
+
+keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
+	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
+	./mkkeywordhash >keywordhash.h
+
+
+
+# Rules to build the extension objects.
+#
+icu.o:	$(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
+
+fts2.o:	$(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
+
+fts2_hash.o:	$(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
+
+fts2_icu.o:	$(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
+
+fts2_porter.o:	$(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
+
+fts2_tokenizer.o:	$(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
+
+fts2_tokenizer1.o:	$(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
+
+fts3.o:	$(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
+
+fts3_expr.o:	$(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
+
+fts3_hash.o:	$(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
+
+fts3_icu.o:	$(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
+
+fts3_porter.o:	$(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
+
+fts3_tokenizer.o:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
+
+fts3_tokenizer1.o:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
+
+rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
+	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
+
+
+# Rules for building test programs and for running tests
+#
+tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
+	$(TCCX_SHARED) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
+		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
+
+
+# Rules to build the 'testfixture' application.
+#
+TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
+TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
+
+testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
+	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
+		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
+		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
+
+amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
+	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
+		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
+		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
+
+fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
+	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
+	-DSQLITE_ENABLE_FTS3=1                                               \
+		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
+		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
+
+fulltest:	testfixture$(EXE) sqlite3$(EXE)
+	./testfixture$(EXE) $(TOP)/test/all.test
+
+soaktest:	testfixture$(EXE) sqlite3$(EXE)
+	./testfixture$(EXE) $(TOP)/test/all.test -soak=1
+
+test:	testfixture$(EXE) sqlite3$(EXE)
+	./testfixture$(EXE) $(TOP)/test/veryquick.test
+
+sqlite3_analyzer$(EXE):	$(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \
+			$(TOP)/tool/spaceanal.tcl
+	sed \
+	  -e '/^#/d' \
+	  -e 's,\\,\\\\,g' \
+	  -e 's,",\\",g' \
+	  -e 's,^,",' \
+	  -e 's,$$,\\n",' \
+	  $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
+	$(TCCX) $(TCL_FLAGS)                  $(TESTFIXTURE_FLAGS)                                 \
+		-DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -DSQLITE_PRIVATE="" \
+		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                    \
+		-o sqlite3_analyzer$(EXE)                                      \
+		$(LIBTCL) $(THREADLIB)
+
+TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
+$(TEST_EXTENSION): $(TOP)/src/test_loadext.c
+	$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
+
+extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
+	./testfixture$(EXE) $(TOP)/test/loadext.test
+
+clean:	
+	rm -f *.o sqlite3$(EXE) libsqlite3.a sqlite3.h opcodes.*
+	rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
+	rm -f $(PUBLISH)
+	rm -f *.da *.bb *.bbg gmon.out
+	rm -rf tsrc target_source
+	rm -f testloadext.dll libtestloadext.so
+	rm -f sqlite3.c fts?amal.c tclsqlite3.c
+	rm -f $(SHPREFIX)sqlite3.$(SO)

+ 39 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/README

@@ -0,0 +1,39 @@
+This directory contains source code to 
+
+    SQLite: An Embeddable SQL Database Engine
+
+To compile the project, first create a directory in which to place
+the build products.  It is recommended, but not required, that the
+build directory be separate from the source directory.  Cd into the
+build directory and then from the build directory run the configure
+script found at the root of the source tree.  Then run "make".
+
+For example:
+
+    tar xzf sqlite.tar.gz    ;#  Unpack the source tree into "sqlite"
+    mkdir bld                ;#  Build will occur in a sibling directory
+    cd bld                   ;#  Change to the build directory
+    ../sqlite/configure      ;#  Run the configure script
+    make                     ;#  Run the makefile.
+    make install             ;#  (Optional) Install the build products
+
+The configure script uses autoconf 2.61 and libtool.  If the configure
+script does not work out for you, there is a generic makefile named
+"Makefile.linux-gcc" in the top directory of the source tree that you
+can copy and edit to suit your needs.  Comments on the generic makefile
+show what changes are needed.
+
+The linux binaries on the website are created using the generic makefile,
+not the configure script.  The windows binaries on the website are created
+using MinGW32 configured as a cross-compiler running under Linux.  For 
+details, see the ./publish.sh script at the top-level of the source tree.
+The developers do not use teh configure script.
+
+SQLite does not require TCL to run, but a TCL installation is required
+by the makefiles.  SQLite contains a lot of generated code and TCL is
+used to do much of that code generation.  The makefile also requires
+AWK.
+
+Contacts:
+
+   http://www.sqlite.org/

+ 1 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/VERSION

@@ -0,0 +1 @@
+3.7.9

+ 7972 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/aclocal.m4

@@ -0,0 +1,7972 @@
+# generated automatically by aclocal 1.10.2 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# 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.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+  ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+  lt_cl_success=:
+  test "$silent" = yes &&
+    lt_config_lt_args="$lt_config_lt_args --quiet"
+  exec AS_MESSAGE_LOG_FD>/dev/null
+  $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+  exec AS_MESSAGE_LOG_FD>>config.log
+  $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_XSI_SHELLFNS
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+[$]*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "[$]0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+    [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+       LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+       [shlibpath_overrides_runpath=yes])])
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC*)
+	    # IBM XL 8.0 on PPC
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        AC_LINK_IFELSE(int foo(void) {},
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+        )
+        LDFLAGS="$save_LDFLAGS"
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+        _LT_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+    [[If ld is used when linking, flag to hardcode $libdir into a binary
+    during linking.  This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+    [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+        # as there is no search path for DLLs.
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+        _LT_TAGVAR(always_export_symbols, $1)=no
+        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    cp $export_symbols $output_objdir/$soname.def;
+          else
+	    echo EXPORTS > $output_objdir/$soname.def;
+	    cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          _LT_TAGVAR(ld_shlibs, $1)=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[[12]]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 will use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  xl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='echo'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=echo
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='echo'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${F77-"f77"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${FC-"f95"}
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]+=\$[2]"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+    ;;
+  esac
+])
+
+# Helper functions for option handling.                    -*- 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 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_SET_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],      [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [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_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],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+
+test -z "$pic_mode" && 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], [])
+
+
+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])])
+
+# 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
+])
+
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 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.
+
+# Generated from ltversion.in.
+
+# serial 3012 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6])
+m4_define([LT_PACKAGE_REVISION], [1.3012])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6'
+macro_revision='1.3012'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007 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 4 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_RC],		[AC_DEFUN([AC_LIBTOOL_RC])])
+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])])
+

+ 34 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/addopcodes.awk

@@ -0,0 +1,34 @@
+#!/usr/bin/awk
+#
+# This script appends additional token codes to the end of the
+# parse.h file that lemon generates.  These extra token codes are
+# not used by the parser.  But they are used by the tokenizer and/or
+# the code generator.
+#
+#
+BEGIN {
+  max = 0
+}
+/^#define TK_/ {
+  print $0
+  if( max<$3 ) max = $3
+}
+END {
+  printf "#define TK_%-29s %4d\n", "TO_TEXT",         ++max
+  printf "#define TK_%-29s %4d\n", "TO_BLOB",         ++max
+  printf "#define TK_%-29s %4d\n", "TO_NUMERIC",      ++max
+  printf "#define TK_%-29s %4d\n", "TO_INT",          ++max
+  printf "#define TK_%-29s %4d\n", "TO_REAL",         ++max
+  printf "#define TK_%-29s %4d\n", "ISNOT",           ++max
+  printf "#define TK_%-29s %4d\n", "END_OF_FILE",     ++max
+  printf "#define TK_%-29s %4d\n", "ILLEGAL",         ++max
+  printf "#define TK_%-29s %4d\n", "SPACE",           ++max
+  printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
+  printf "#define TK_%-29s %4d\n", "FUNCTION",        ++max
+  printf "#define TK_%-29s %4d\n", "COLUMN",          ++max
+  printf "#define TK_%-29s %4d\n", "AGG_FUNCTION",    ++max
+  printf "#define TK_%-29s %4d\n", "AGG_COLUMN",      ++max
+  printf "#define TK_%-29s %4d\n", "CONST_FUNC",      ++max
+  printf "#define TK_%-29s %4d\n", "UMINUS",          ++max
+  printf "#define TK_%-29s %4d\n", "UPLUS",           ++max
+}

BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/2005osaward.gif


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite.eps


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite.gif


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLiteLogo3.tiff


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/SQLite_big.gif


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/nocopy.gif


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/powered_by_sqlite.gif


Plik diff jest za duży
+ 13 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.eps


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.ico


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/sqlite370.jpg


BIN
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/art/src_logo.gif


+ 1535 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.guess

@@ -0,0 +1,1535 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2007-07-22'
+
+# This file 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+if [ "${UNAME_SYSTEM}" = "Linux" ] ; then
+	eval $set_cc_for_build
+	cat << EOF > $dummy.c
+	#include <features.h>
+	#ifdef __UCLIBC__
+	# ifdef __UCLIBC_CONFIG_VERSION__
+	LIBC=uclibc __UCLIBC_CONFIG_VERSION__
+	# else
+	LIBC=uclibc
+	# endif
+	#else
+	LIBC=gnu
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep LIBC= | sed -e 's: ::g'`
+fi
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:[3456]*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    EM64T | authenticamd)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-${LIBC}
+	exit ;;
+    xtensa:Linux:*:*)
+    	echo xtensa-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-${LIBC}"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}aout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}coff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}oldld"
+		exit ;;
+	esac
+	# This should get integrated into the C code below, but now we hack
+	if [ "$LIBC" != "gnu" ] ; then echo "$TENTATIVE" && exit 0 ; fi
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

+ 108 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.h

@@ -0,0 +1,108 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `fdatasync' function. */
+#define HAVE_FDATASYNC 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* Define to 1 if the system has the type `int16_t'. */
+#define HAVE_INT16_T 1
+
+/* Define to 1 if the system has the type `int32_t'. */
+#define HAVE_INT32_T 1
+
+/* Define to 1 if the system has the type `int64_t'. */
+#define HAVE_INT64_T 1
+
+/* Define to 1 if the system has the type `int8_t'. */
+#define HAVE_INT8_T 1
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#define HAVE_INTPTR_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if you have the `localtime_s' function. */
+/* #undef HAVE_LOCALTIME_S */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#define HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#define HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#define HAVE_UINT8_T 1
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the utime() library function. */
+#define HAVE_UTIME 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "sqlite"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "sqlite 3.7.9"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "sqlite"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.7.9"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */

+ 107 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.h.in

@@ -0,0 +1,107 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#undef HAVE_GMTIME_R
+
+/* Define to 1 if the system has the type `int16_t'. */
+#undef HAVE_INT16_T
+
+/* Define to 1 if the system has the type `int32_t'. */
+#undef HAVE_INT32_T
+
+/* Define to 1 if the system has the type `int64_t'. */
+#undef HAVE_INT64_T
+
+/* Define to 1 if the system has the type `int8_t'. */
+#undef HAVE_INT8_T
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#undef HAVE_INTPTR_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define to 1 if you have the `localtime_s' function. */
+#undef HAVE_LOCALTIME_S
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#undef HAVE_UINT16_T
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#undef HAVE_UINT32_T
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#undef HAVE_UINT8_T
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `usleep' function. */
+#undef HAVE_USLEEP
+
+/* Define to 1 if you have the utime() library function. */
+#undef HAVE_UTIME
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES

+ 1644 - 0
components/dfs/filesystems/uffs/src/test/sqlite3/sqlite-src-3070900/config.sub

@@ -0,0 +1,1644 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2007-06-28'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx | dvp \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]a*eb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]a*eb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mipsEE* | ee | ps2)
+		basic_machine=mips64r5900el-scei
+		case $os in
+		    -linux*)
+			;;
+		    *)
+			os=-elf
+			;;
+		esac
+		;;
+	iop)
+		basic_machine=mipsel-scei
+		os=-irx
+		;;
+	dvp)
+		basic_machine=dvp-scei
+		os=-elf
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -irx*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików