summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRitesh Raj Sarraf <rrs@researchut.com>2010-05-20 01:24:17 +0530
committerRitesh Raj Sarraf <rrs@researchut.com>2010-05-20 01:24:17 +0530
commita2c4d1e83d89a4451726b769faf855eb02d15cb3 (patch)
treec219ad091ab092b2357423a8b413d85b18240a00
Imported Upstream version 1.0.7upstream/1.0.7
-rw-r--r--AUTHORS1
-rw-r--r--COPYING340
-rw-r--r--ChangeLog681
-rw-r--r--INSTALL182
-rw-r--r--Makefile.am47
-rw-r--r--Makefile.in695
-rw-r--r--NEWS0
-rw-r--r--README99
-rw-r--r--TODO637
-rw-r--r--aclocal.m41019
-rw-r--r--binfile.c593
-rw-r--r--binfile.h52
-rw-r--r--config.h.in22
-rwxr-xr-xconfigure4750
-rw-r--r--configure.ac107
-rwxr-xr-xdepcomp479
-rwxr-xr-xinstall-sh294
-rwxr-xr-xmissing336
-rwxr-xr-xmkinstalldirs111
-rw-r--r--module/Makefile72
-rw-r--r--module/sysprof-module.c267
-rw-r--r--module/sysprof-module.h37
-rw-r--r--process.c444
-rw-r--r--process.h61
-rw-r--r--profile.c878
-rw-r--r--profile.h76
-rw-r--r--sfile.c1980
-rw-r--r--sfile.h143
-rw-r--r--stackstash.c218
-rw-r--r--stackstash.h45
-rw-r--r--sysprof-icon.pngbin0 -> 3761 bytes
-rw-r--r--sysprof.c1559
-rw-r--r--sysprof.glade565
-rw-r--r--treeviewutils.c232
-rw-r--r--treeviewutils.h45
-rw-r--r--watch.c328
-rw-r--r--watch.h40
37 files changed, 17435 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a8d0fae
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Søren Sandmann (sandmann@redhat.com)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 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 Library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..db6b6c7
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,681 @@
+2006-11-16 Soren Sandmann <sandmann@daimi.au.dk>
+
+ * =-=-=-= Release 1.0.7 =-=-=-=
+
+ * process.c (process_lookup_symbol): Also treat 0x01 as "In
+ kernel", even when there is a map for the 0x00 address. (Tim
+ Rowley).
+
+ * module/sysprof-module.c: Check for profiling enabled after
+ potentially including config.h
+
+2006-11-02 Soren Sandmann <sandmann@daimi.au.dk>
+
+ * -=-=-=- Release sysprof 1.0.6 -=-=-=-
+
+ * module/sysprof-module.c: Include config.h on kernels < 2.6.18.
+
+2006-10-29 Soren Sandmann <sandmann@daimi.au.dk>
+
+ * -=-=-=- Release sysprof 1.0.5 -=-=-=-
+
+ * binfile.c (read_symbols): Store symbols in offsets into original
+ file, not debug file. Fixes symbols when the debug binaries have
+ different text offsets than the real binaries.
+
+2006-10-29 Soren Sandmann <sandmann@daimi.au.dk>
+
+ * =-=-=-= Release sysprof 1.0.4 =-=-=-=
+
+ * module/sysprof-module.c: Remove include of linux/config.h
+
+Sat Aug 12 16:27:13 2006 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (timer_notify): Bugfix for SMP kernel:
+ Make n_samples a per-CPU variable. Protect timer_notify() with an
+ atomic variable.
+
+2006-06-08 Soren Sandmann <sandmann@redhat.com>
+
+ * announce-1.0.3: Fix forgotten 1.0.2 -> 1.0.3.
+
+2006-06-08 Soren Sandmann <sandmann@redhat.com>
+
+ * =-=-=-= Release sysprof 1.0.3 =-=-=-=
+
+ * configure.ac: Bump version number
+
+ * announce-1.0.3: Add this file.
+
+ * sysprof.c (RESET_DEAD_PERIOD): Increase this to 250
+
+2006-06-05 Soren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (init_module): Copy the proc_fops and
+ update the poll entry in the copy, rather than writing directly to
+ the proc_fops. Fixes compilation on the latest kernels.
+
+Thu Feb 23 21:37:21 2006 Soeren Sandmann <sandmann@redhat.com>
+
+ * =-=-=-= Release sysprof 1.0.2 =-=-=-=
+
+ * configure.ac: Bump version number
+
+ * sysprof.c (on_about_activated): Update about box
+
+ * announce-1.0.2: add this file
+
+Sun Jan 15 20:16:39 2006 Soeren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c: Add package version to spew.
+
+2006-01-13 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (INTERVAL): Backport fix for HZ <=
+ SAMPLES_PER_SECOND from HEAD. (Thomas de Grenier de Latour).
+
+Wed Jan 11 20:23:06 2006 Søren Sandmann <sandmann@redhat.com>
+
+ * process.c (read_maps): Also make offset a gulong (Samuel
+ Mimram).
+
+Mon Jan 9 09:56:46 2006 Soeren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (timer_notify): Remove START_OF_STACK
+ check.
+
+Mon Jan 9 00:53:35 2006 Soeren Sandmann <sandmann@redhat.com>
+
+ * process.c (read_maps): Use gulong for addresses. Bug reported by
+ Martin Reddy.
+
+Tue Dec 20 12:21:16 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * configure.ac: Add missing backslashes, pointed out by Ralph
+ Siemsen.
+
+Mon Dec 19 15:46:27 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * =-=-=-= Release sysprof 1.0.1 =-=-=-=
+
+ * configure.ac: Bump version numbers
+
+Mon Dec 19 15:39:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (timer_notify): Make kernel module
+ compile with recent kernels. Delete lots of commented out code.
+
+Sat Oct 29 14:43:00 2005 Søren Sandmann <sandmann@redhat.com>
+
+ Fix crash pointed reported by Rudi Chiarito.
+
+ * stackstash.c (stack_stash_add_trace): Just return if
+ n_addrs is 0.
+
+ * sysprof.c (on_read): Only trace if n_addresses != 0.
+
+Mon Oct 10 14:33:50 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * configure.ac: Add --disable-kernel-module option. Patch from
+ Pascal Terjan.
+
+Sat Sep 17 14:35:32 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * Bump version numbers
+ * README: update
+ * TODO: Updates
+
+Sun Sep 4 19:38:51 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Tue Aug 30 16:57:33 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * configure.ac: Complain if we can't find /lib/modules/`uname
+ -r`/build/Makefile.
+
+ * process.c (process_lookup_symbol): Take an address of 0x1 to
+ mean "in kernel".
+
+ * module/sysprof-module.c (timer_notify): When reporting in-kernel
+ time, give the current pid instead of -1.
+
+ * TODO: updates
+
+Mon Aug 15 20:39:11 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * binfile.c, process.c, profile.c: Fix some warnings.
+
+Mon Aug 1 23:49:51 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (REG_INS_PTR): Add support for
+ amd64/x86-64. Patch from Mike Frysinger.
+
+Sun Jul 10 10:51:52 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * binfile.c: Various minor clean-ups
+
+Sat Jul 9 23:20:39 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * binfile.c (bin_file_new): Cache BinFiles by filename.
+
+ * stackstash.c (stack_stash_free): Plug leak
+
+ * process.c (process_free_maps): Plug leak
+
+ * module/Makefile (install): Check that depmod exists before
+ running it.
+
+Sun Jun 19 15:42:34 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c (SAMPLES_PER_SECOND): Set to 200.
+
+ * sysprof.c (on_about_activated): Add version information
+
+ * configure.ac: Bump version to 0.91
+
+ * README: Updates
+
+Sat Jun 18 22:45:04 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+ * configure.ac: Check for Linux 2.6.11
+
+ * process.c (get_pidname): Present pid=-1 as [kernel].
+
+ * module/sysprof-module.c: Use register_timer_hook() instead of
+ a kernel timer. Set trace.pid to -1 if interrupt happens in
+ kernel.
+
+Sun Jun 12 20:30:37 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (build_gui): Disable type-ahead search for all the
+ tree views.
+
+ * sysprof.c (on_object_selection_changed): Call it from here
+
+ * sysprof.c (expand_descendants_tree): New function that
+ determines what nodes to expand in the descendatns view.
+
+Sun Jun 12 13:37:15 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Thu Jun 9 13:28:33 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Thu May 26 01:10:45 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (on_callers_row_activated): Grab focus on the callers
+ view, not the descendants view.
+
+ * sysprof.c (on_read): Add a short "dead" period after a reset,
+ so that 'samples' will actually be 0 for a while.
+
+Mon May 23 01:37:26 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * README: Remove comment about auto* stuff, link to
+
+ http://www.daimi.au.dk/~sandmann/sysprof/
+
+Sun May 23 16:10:00 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ -=-=-=-=-=- Release v. 0.9 -=-=-=-=-=-
+
+Sun May 22 21:06:36 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Sat May 21 20:58:59 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: update
+
+ * sysprof.c (on_menu_item_activated): New function.
+
+ * sysprof.c (build_gui): Hook up menu items.
+
+ * module/sysprof-module.c (init_module): Remove module_init/exit
+ as they cause build failure on kernels < 2.6.11.
+
+Sat May 21 00:59:38 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: update
+
+Wed May 18 22:21:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c: Remove ref-counting since it didn't
+ actually do any good.
+
+ * sysprof.c (load_module): Use g_spawn_command_line_sync() instaed
+ of system().
+
+Sun May 15 11:56:30 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * module/sysprof-module.c: First attempt at making module robust
+ agains unloading when in use.
+
+Sun May 15 10:24:09 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * Makefile.am, module/Makefile: Do more-or-less what the automake
+ manual suggests about foreign subdirectories.
+
+Sat May 14 16:36:32 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (set_application_title): Update the title bar on
+ load/save
+
+ * treeviewutils.c, sfile.c: Fix compiler warnings
+
+ * Makefile.am: define PIXMAPDIR
+
+Sat May 14 15:49:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ Auto*ify.
+
+ * TODO: updates
+
+ * AUTHORS, INSTALL, Makefile.am, NEWS, configure.ac: New files
+
+ * module/Makefile: New file
+
+ * module/sysprof-module.c, module/sysprof-module.h: Move these
+ files to their own directy, as the kernel build system does not
+ work very well with auto*.
+
+ * sysprof.c, autogen.sh: Some auto* changes.
+
+Sun May 8 16:31:32 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: more updates
+
+ * sysprof.c: Try loading the module before complaining
+
+Sun May 8 15:45:08 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (do_generate): Restore lost wake_up().
+
+ * sfile.c: Comment out use of bz2.
+
+ * Makefile: Add an install target. Add GLADE_DIR and PIXMAP_DIR
+
+ * sysprof.c (build_gui): use GLADE_DIR and PIXMAP_DIR here.
+
+ * TODO: Updates.
+
+Sat May 7 13:57:17 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sfile.c (sfile_output_free): Implement this function
+
+ * sfile.c (sfile_input_free): Implement this function
+
+Fri May 6 23:38:48 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (do_generate): Another desparate hack to try
+ and prevent the oops.
+
+Sat Apr 30 16:57:23 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * process.c (PAGE_SIZE): Use getpagesize()
+
+ * TODO: More updates
+
+Sat Apr 30 15:44:12 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+ * sysprof-module.c (get_regs): Change the way we get registers for
+ a task so that it works with 2.6.11
+
+Sat Apr 23 19:17:18 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Sat Apr 23 19:12:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * profile.c: Store a pointer to the root of the call tree
+
+ * profile.c (profile_load): Call sfile_input_free()
+
+ * sfile.c (sformat_free): Implement this function
+
+Sat Apr 23 18:38:46 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sfile.c (post_process_read_instructions): Check pointer types
+
+ * sfile.c (post_process_instructions_recurse): Delete this unused function
+
+Sat Apr 23 17:49:33 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (page_readable): New function to check if the
+ page is readable before reading. Noop on kernel <= 2.6.11
+
+ * sysprof-module.c (get_mm, put_mm): New functions to confine
+ #ifdefs.
+
+Sat Apr 23 17:48:22 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * Makefile (MODCFLAGS): Disable optimization as I suspect
+ the oops is related to miscompilation.
+
+Fri Apr 22 00:09:16 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (read_user_space): On >= 2.6.11 check that the
+ pages are present and readable before reading them.
+
+Tue Apr 19 23:26:45 2005 Kristian Høgsberg <krh@bitplanet.net>
+
+ * Makefile (check): Add simple check target that runs a sanity
+ check of the build environment.
+
+Sun Apr 17 00:20:41 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (on_open_clicked): Factor out some stuff in their own
+ functions.
+
+ * sysprof.c (load_file): Idle handler to load files given on the
+ command line.
+
+ * sysprof.c (main): If a filename is passed on the command line,
+ load it in an idle handler.
+
+Sun Apr 17 00:19:03 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+Sat Apr 16 19:51:48 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (read_user_space): Read a whole page at a time.
+
+Sat Apr 16 14:15:55 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Update
+
+ * sysprof-module.c (x_access_process_vm): On kernel 2.6.9 and
+ later use get_task_mm()/mmput() instead of directly accessing
+ task->mm.
+
+Sat Apr 16 01:54:18 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Add backtrace for kernel oops.
+
+Fri Apr 15 16:37:45 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: updates
+
+ * sysprof.c (sorry): If you hit profile when the module isn't
+ loaded, pop up an annoying dialog.
+
+ * sysprof-module.c: Clean-ups, remove various unused abstractions.
+
+Sat Apr 9 17:49:13 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * COPYING: Add a copy of the GPL
+
+Sat Apr 9 17:04:50 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * Makefile: Remove debug spew
+
+ * *: Add copyright notices
+
+Fri Apr 8 21:30:02 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: More updates
+
+Fri Apr 8 20:48:58 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (build_gui): Load the icon, hook up "about"
+ activation.
+
+ * sysprof.c (on_about_activated): New function. Show an about
+ dialog.
+
+ * sysprof.c (struct Application): Add an icon field
+
+ * TODO: Updates
+
+ * sysprof-icon.png: Icon, drawn by Diana Fong
+
+Tue Apr 5 23:01:02 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * binfile.c (read_symbols): Put back the weird loop, and stop
+ pretending I understand this. This time use SEC_ALLOC instead of
+ SEC_LOAD.
+
+Tue Apr 5 20:13:44 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * process.c (process_ensure_map): Add commented out debug spew.
+
+ * process.c (process_lookup_symbol): Remove all should_offset()
+ function and all references to it.
+
+ * binfile.c (bin_file_lookup_symbol): Document that address must
+ be in file coordinates.
+
+ * binfile.c (read_symbols): Remove misguided code that tried to
+ guess the load address of the file. Instead, do all computations
+ in "file coordinates". Also fix a memory leak. Add commented out
+ debug spew.
+
+ * binfile.c (separate_debug_file_exists): Fix signedness
+
+Tue Apr 5 14:34:43 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (x_access_process_vm): Make it compile with
+ kernel 2.6.11
+
+ * TODO: updates
+
+Mon Apr 4 00:57:11 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c: Busy cursors in many more places.
+
+ * TODO: updates
+
+Sun Apr 3 23:28:45 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (do_generate): Re-schedule the timeout here
+ instead of in on_timer().
+
+ * sysprof-module.c (on_timer): Only block tasks in the
+ TASK_RUNNING state.
+
+Sun Apr 3 17:03:33 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (queue_generate_stack_trace): Put current
+ process to sleep.
+
+ * sysprof-module.c (do_generate): Wake up the traced process
+
+Thu Mar 31 23:09:09 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (build_gui): Remove stray %
+
+Thu Mar 31 21:18:13 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * treeviewutils.c (add_double_format_column): Right justify numbers
+
+ * sysprof.c (build_gui): Add a space after the numbers
+
+ * sysprof.c (on_callers_row_activated): Focus object view
+
+ * sysprof.c (on_descendants_row_activated): Focus new descendants
+ tree.
+
+Thu Mar 31 19:51:51 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c (do_generate): Walk all threads, not just all
+ processes.
+
+ * TODO: Add disk profiling ideas
+
+Thu Mar 31 00:19:47 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (set_busy): Make this function work
+
+ * sysprof.c (on_profile_toggled): Use it here
+
+ * sysprof.c (on_object_selection_changed): And here
+
+ * profile.c (add_trace_to_tree): Use GPtrArrays instead of
+ GHashTable and GList.
+
+Mon Mar 28 11:09:02 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: updates
+
+Sat Mar 26 19:26:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c: Show the right number of samples afte Open; remove
+ shadows from menu bars and toolbars; some other tweaks.
+
+Sat Mar 26 11:26:00 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * TODO: Updates
+
+ * sfile.c (add_string): Use g_markup_escape_text() to escape the
+ string before adding it to the file.
+
+ * sysprof.c (empty_file_descriptor): New function to make sure
+ samples generated before profiling started are ignored.
+ (set_busy): New commented out function to set a busy cursor.
+
+Fri Mar 25 21:31:08 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (update_sensitivity): Comment out sensitivity of reset button.
+
+Fri Mar 25 21:25:31 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (get_current_object): Return NULL if nothing is
+ selected.
+
+Fri Mar 25 20:54:08 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: More updates
+
+Fri Mar 25 20:25:44 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * README: Require gtk+ 2.6
+
+ * treeviewutils.c (add_plain_text_column): Ellipsisize text columns.
+
+Fri Mar 25 19:39:24 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * TODO: Remove "loading and saving"
+
+ * sysprof.glade: Add ellipsises to Open and Save menu items.
+
+ * sysprof.c (overwrite_file): Add this function, cutted-and-pasted
+ from evince.
+
+ * sysprof.c (on_save_as_clicked, on_open_clicked): Use
+ GtkFileChoosers to pick the names.
+
+ * sysprof.c: Various GUI updates.
+
+Fri Mar 25 19:36:28 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sfile.c (bz2_compress): Add this function Don't actually make
+ any produce use of it.
+
+ * profile.c (make_hash_table): Get rid of warning
+
+Thu Mar 24 19:09:33 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c: Various GUI updates
+
+ * TODO: update
+
+ * sfile.[ch] (sformat_new_optional): Add some notes about an
+ "optional" construction.
+
+Wed Mar 23 00:04:07 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ Primitive loading and saving.
+
+ * sysprof.c (on_open_clicked): Hook up loading.
+
+ * sfile.c: Add a copy of g_file_replace() from glib CVS HEAD.
+
+ * sfile.c (add_string): Escape and quote the string
+
+ * sfile.c (sfile_load): Initialize current_instruction and
+ instructions_by_location
+
+ * sfile.c (post_process_instructions_recurse): Handle NULL
+ pointers properly.
+
+ * sfile.c (handle_begin_element, handle_end_element, handle_text):
+ Move error handling here from state_transition_begin/text/end.
+
+ * sfile.c (handle_text): Discard whitespace-only strings
+
+ * sfile.c (sfile_get_pointer, sfile_get_integer,
+ sfile_get_string): expect both begin, value, and end transitions.
+
+ * sfile.c (hook_up_pointers): Only treat instructions as pointer
+ values when they are. Handle NULL targets properly.
+
+ * sfile.c (get_number): Fix a few read-freed-data bugs
+
+ * profile.c (profile_load): Call sfile_end_get() for the profile;
+ build the nodes_by_objects hash table. Build the call tree.
+
+ * profile.c (create_format): Don't store next pointer, but do
+ store total, self and toplevel.
+
+ * profile.c (make_hash_table): New function to build
+ nodes_by_object hashtable from loaded data
+
+Sat Mar 12 11:05:19 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sysprof-module.c: Fix small bug in add_timeout()
+ * sysprof.c (build_gui): More descriptive tree labels
+ * TODO: update
+
+Thu Mar 10 16:37:52 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c (build_gui): s/Cummulative/Cumulative/. Pointed out by
+ Ian McIntosh.
+
+Mon Mar 7 14:47:09 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * README: Add note that you need to compile the module with
+ the same compiler that compiled the kernel.
+
+Sun Mar 6 22:56:21 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sfile.c: Generate id's for objects and pointers.
+
+Sat Mar 5 01:09:33 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * sfile.c: Bug fixes. Add actual generation.
+
+Fri Mar 4 13:47:13 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * sysprof.c: Remove include of non-existing tracing.h
+
+Thu Mar 3 23:48:13 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * profile.c (profile_load): Write this function.
+
+ * sfile.c: Add support for user defined record and list types.
+ Simplify logic a lot.
+
+Wed Mar 2 23:39:50 2005 Soeren Sandmann <sandmann@redhat.com>
+
+ * profile.[ch], sfile.[ch]: Experiment with a
+ file-format-description format.
+
+ * sysprof.c: Add commented out code using /proc/ based
+ timeout.
+
+Fri Jan 21 11:23:54 2005 Søren Sandmann <sandmann@redhat.com>
+
+ * README: Some updates - add note about SMP kernels.
+
+ * sysprof-module.c: Go back to just sampling the current
+ process.
+
+ * ChangeLog: I guess these do make sense, so start one.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..b42a17a
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..485754e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,47 @@
+SUBDIRS = $(MODULE_SUBDIR)
+DIST_SUBDIRS = module
+
+bin_PROGRAMS = sysprof
+pkgdata_DATA = sysprof.glade sysprof-icon.png
+
+sysprof_SOURCES = \
+ binfile.h \
+ binfile.c \
+ process.h \
+ process.c \
+ profile.h \
+ profile.c \
+ sfile.h \
+ sfile.c \
+ stackstash.h \
+ stackstash.c \
+ module/sysprof-module.h \
+ sysprof.c \
+ treeviewutils.h \
+ treeviewutils.c \
+ watch.h \
+ watch.c
+
+sysprof_LDADD = $(DEP_LIBS)
+
+INCLUDES = \
+ $(DEP_CFLAGS) \
+ -DDATADIR=\"$(pkgdatadir)\" \
+ -DPIXMAPDIR=\"$(datadir)/pixmaps\"
+
+# memprof.desktop
+# memprof.spec.in
+
+EXTRA_DIST = \
+ sysprof.glade \
+ sysprof-icon.png \
+ module/sysprof-module.c \
+ module/sysprof-module.h \
+ module/Makefile
+
+pixmapsdir = $(datadir)/pixmaps
+pixmaps_DATA = sysprof-icon.png
+
+insert-module:
+ modprobe -r sysprof-module
+ modprobe sysprof-module
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..9d2722f
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,695 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DEP_CFLAGS = @DEP_CFLAGS@
+DEP_LIBS = @DEP_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MODULE_SUBDIR = @MODULE_SUBDIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+SUBDIRS = $(MODULE_SUBDIR)
+DIST_SUBDIRS = module
+
+bin_PROGRAMS = sysprof
+pkgdata_DATA = sysprof.glade sysprof-icon.png
+
+sysprof_SOURCES = \
+ binfile.h \
+ binfile.c \
+ process.h \
+ process.c \
+ profile.h \
+ profile.c \
+ sfile.h \
+ sfile.c \
+ stackstash.h \
+ stackstash.c \
+ module/sysprof-module.h \
+ sysprof.c \
+ treeviewutils.h \
+ treeviewutils.c \
+ watch.h \
+ watch.c
+
+
+sysprof_LDADD = $(DEP_LIBS)
+
+INCLUDES = \
+ $(DEP_CFLAGS) \
+ -DDATADIR=\"$(pkgdatadir)\" \
+ -DPIXMAPDIR=\"$(datadir)/pixmaps\"
+
+
+
+# memprof.desktop
+# memprof.spec.in
+EXTRA_DIST = \
+ sysprof.glade \
+ sysprof-icon.png \
+ module/sysprof-module.c \
+ module/sysprof-module.h \
+ module/Makefile
+
+
+pixmapsdir = $(datadir)/pixmaps
+pixmaps_DATA = sysprof-icon.png
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+bin_PROGRAMS = sysprof$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+
+am_sysprof_OBJECTS = binfile.$(OBJEXT) process.$(OBJEXT) \
+ profile.$(OBJEXT) sfile.$(OBJEXT) stackstash.$(OBJEXT) \
+ sysprof.$(OBJEXT) treeviewutils.$(OBJEXT) watch.$(OBJEXT)
+sysprof_OBJECTS = $(am_sysprof_OBJECTS)
+sysprof_DEPENDENCIES =
+sysprof_LDFLAGS =
+
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/binfile.Po ./$(DEPDIR)/process.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/profile.Po ./$(DEPDIR)/sfile.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/stackstash.Po ./$(DEPDIR)/sysprof.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/treeviewutils.Po ./$(DEPDIR)/watch.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(sysprof_SOURCES)
+DATA = $(pixmaps_DATA) $(pkgdata_DATA)
+
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+ ps-recursive install-info-recursive uninstall-info-recursive \
+ all-recursive install-data-recursive install-exec-recursive \
+ installdirs-recursive install-recursive uninstall-recursive \
+ check-recursive installcheck-recursive
+DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \
+ COPYING ChangeLog INSTALL Makefile.am NEWS TODO aclocal.m4 \
+ config.h.in configure configure.ac depcomp install-sh missing \
+ mkinstalldirs
+SOURCES = $(sysprof_SOURCES)
+
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
+
+$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.ac $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+$(ACLOCAL_M4): configure.ac
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+
+$(srcdir)/config.h.in: $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ touch $(srcdir)/config.h.in
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
+ rm -f $(DESTDIR)$(bindir)/$$f; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+sysprof$(EXEEXT): $(sysprof_OBJECTS) $(sysprof_DEPENDENCIES)
+ @rm -f sysprof$(EXEEXT)
+ $(LINK) $(sysprof_LDFLAGS) $(sysprof_OBJECTS) $(sysprof_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stackstash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysprof.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/treeviewutils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+uninstall-info-am:
+pixmapsDATA_INSTALL = $(INSTALL_DATA)
+install-pixmapsDATA: $(pixmaps_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pixmapsdir)
+ @list='$(pixmaps_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(pixmapsDATA_INSTALL) $$d$$p $(DESTDIR)$(pixmapsdir)/$$f"; \
+ $(pixmapsDATA_INSTALL) $$d$$p $(DESTDIR)$(pixmapsdir)/$$f; \
+ done
+
+uninstall-pixmapsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pixmaps_DATA)'; for p in $$list; do \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " rm -f $(DESTDIR)$(pixmapsdir)/$$f"; \
+ rm -f $(DESTDIR)$(pixmapsdir)/$$f; \
+ done
+pkgdataDATA_INSTALL = $(INSTALL_DATA)
+install-pkgdataDATA: $(pkgdata_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f"; \
+ $(pkgdataDATA_INSTALL) $$d$$p $(DESTDIR)$(pkgdatadir)/$$f; \
+ done
+
+uninstall-pkgdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " rm -f $(DESTDIR)$(pkgdatadir)/$$f"; \
+ rm -f $(DESTDIR)$(pkgdatadir)/$$f; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if (etags --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ else \
+ include_option=--include; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = .
+distdir = $(PACKAGE)-$(VERSION)
+
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ mkdir $(distdir)
+ $(mkinstalldirs) $(distdir)/module
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ $(am__remove_distdir)
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
+ && rm -f $(distdir).tar.gz \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @echo "$(distdir).tar.gz is ready for distribution" | \
+ sed 'h;s/./=/g;p;x;p;x'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS) $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(pixmapsdir) $(DESTDIR)$(pkgdatadir)
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic distclean-hdr \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pixmapsDATA install-pkgdataDATA
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am \
+ uninstall-pixmapsDATA uninstall-pkgdataDATA
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+ clean-binPROGRAMS clean-generic clean-recursive ctags \
+ ctags-recursive dist dist-all dist-gzip distcheck distclean \
+ distclean-compile distclean-generic distclean-hdr \
+ distclean-recursive distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am dvi-recursive info info-am \
+ info-recursive install install-am install-binPROGRAMS \
+ install-data install-data-am install-data-recursive \
+ install-exec install-exec-am install-exec-recursive \
+ install-info install-info-am install-info-recursive install-man \
+ install-pixmapsDATA install-pkgdataDATA install-recursive \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am installdirs-recursive maintainer-clean \
+ maintainer-clean-generic maintainer-clean-recursive mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-recursive \
+ pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
+ tags-recursive uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-info-am uninstall-info-recursive \
+ uninstall-pixmapsDATA uninstall-pkgdataDATA uninstall-recursive
+
+
+insert-module:
+ modprobe -r sysprof-module
+ modprobe sysprof-module
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..04ef77c
--- /dev/null
+++ b/README
@@ -0,0 +1,99 @@
+Sysprof is a sampling profiler that uses a kernel module to generate
+stacktraces which are then interpreted by the userspace program
+"sysprof".
+
+See the Sysprof homepage:
+
+ http://www.daimi.au.dk/~sandmann/sysprof/
+
+for more information
+
+Please mail bug reports to
+
+ Soren Sandmann (sandmann@daimi.au.dk)
+
+Also information about whether it works or doesn't work on your distribution
+would be appreciated.
+
+
+
+
+Requirements:
+
+- A Linux kernel version 2.6.11 or newer is required.
+ Unlike Sysprof 0.9, this version should work fine on SMP systems.
+
+- GTK+ 2.6.0 or newer is required
+
+- libglade 2.5.1 is required
+
+
+Compiling:
+
+- Sysprof must be compiled with the same compiler that compiled the
+ kernel it is going to be used with. Usually this is just the the
+ system compiler, but if you have upgraded your kernel it is
+ possible that the new kernel was compiled with a different compiler
+
+ In that case, "modprobe sysprof-module" will produce this
+ error message:
+
+ insmod: error inserting './sysprof-module.o': -1 Invalid module format
+
+
+
+Debugging symbols
+
+- The programs you want to profile should have debugging symbols, or
+ you won't get much usable information. On a Fedora Core system,
+ installing the relevant -debuginfo package should be sufficient.
+
+
+- X server.
+
+ The X server as shipped by most distributions uses its own home-rolled
+ module loading system and Sysprof has no way to deal with that, so if you
+ run sysprof with your normal X serverr you won't get any information about
+ how time is spent inside the X server.
+
+ To fix this you have to compile your own X server:
+
+ (1) Compile the X server to use ".so" modules:
+
+ - Uncomment the line "MakeDllModules Yes" in
+ xc/config/cf/xorgsite.def.
+
+ If you are compiling the CVS version of the X server
+ (the one that will eventually become 7.0), then this is
+ already the default.
+
+ - "make World"
+
+ (2) Install the X server making sure it can't see any ".a" files. If
+ you install on top of an existing installation, just do
+
+ find /usr/X11R6/lib/"*.a" | sudo xargs rm
+
+ and install the newly compiled X server.
+
+ If a ".so" X server finds .a files in its module path it will
+ try to load those in preference to .so files and this causes
+ symbol resolution problems
+
+ (3) Run your new X server
+
+ (4) Run sysprof as root. This is necessary because the X server binary
+ for security reasons is not readable by regular users. I could tell
+ you why, but then I'd have to kill you.
+
+
+
+
+Credits:
+ Diana Fong for the icon
+ Mike Frysinger for x86-64 support
+ Kristian Høgsberg for the first port to the 2.6 kernel.
+ Owen Taylor for the symbol lookup code in memprof
+
+
+Søren (sandmann@daimi.au.dk)
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..85fdd8f
--- /dev/null
+++ b/TODO
@@ -0,0 +1,637 @@
+Before 1.0:
+
+ - Update version numbers in source
+
+ - Make tarball
+
+ - Check that tarball works
+
+ - cvs commit
+
+ - cvs tag sysprof-1-0
+
+ - Update website
+
+ - Announce on Freshmeat
+
+ - Announce on gnome-announce
+ - Announce on kernel list.
+
+ - Announce on Gnomefiles
+
+ - Announce on news.gnome.org
+ - Send to slashdot/developers
+ - Announce on devtools list (?)
+
+ - Announce on Advogato
+ link to archive
+
+Before 1.0.1:
+
+* See if we can reproduce the problem where libraries didn't get correctly
+ reloaded after new versions were installed.
+
+* Build system
+ - Find out what distributions it actually works on
+ (ask for sucess/failure-stories in 1.0 releases)
+
+ - Create RPM package? See fedora-packaging-list for information
+ about how to package kernel modules. Lots of threads in
+ June 2005 and forward.
+
+ See also http://www.fedoraproject.org/wiki/Extras/KernelModuleProposal
+
+Before 1.2:
+
+* See if the auto-expanding can be made more intelligent
+
+* Send entire stack to user space, then do stackwalking there. That would
+ allow us to do more complex algorithms, like dwarf, in userspace. Though
+ we'd lose the ability to do non-racy file naming. We could pass a list
+ of the process mappings with each stack though.
+
+* If interrupt happens in kernel mode, send both
+ kernel stack and user space stack, have userspace stitch them
+ together. (User space stack must probably be done in a thread - kernel
+ stack must probably be taken in the interrupt itself?
+ - Why this difference? The page tables should still be loaded. Is it
+ because pages_present() doesn't work? No, turning it off doesn't help.
+ - It looks like this works. Get:
+
+ struct pt_regs *user_regs =
+ (void *)current->thread.esp0 - sizeof (struct pt_regs);
+
+ then use pages_present as usual to trace with user_regs; There could be
+ rare lockups though.
+
+* Correctness
+ - When the module is unloaded, kill all processes blocking in read
+ - or block unloading until all processes have exited
+ Unfortunately this is basically impossible to do with a /proc
+ file (no open() notification). So, for 1.0 this will have to be
+ a dont-do-that-then. For 1.2, we should do it with a sysfs and
+ kobject instead.
+
+ - When the module is unloaded, can we somehow *guarantee* that no
+ kernel thread is active? Doesn't look like it; however we can
+ get close by decreasing a ref count just before returning
+ from the module. (There may still be return instructions etc.
+ that will get run). This may not be an issue with the timer
+ based scanning we are using currently.
+
+- See if there is a way to make it distcheck
+
+- grep FIXME - not10
+
+- translation should be hooked up
+
+- Consider adding "at least 5% inclusive cost" filter
+
+- consider having the ability to group a function together with its nearest
+ neighbours. That way we can eliminate some of the effect of
+ "one function taking 10% of the time"
+ vs.
+ "the same function broken into ten functions each taking 1%"
+ Not clear what the UI looks like though.
+
+- Ability to generate "screenshots" suitable for mail/blog/etc
+ UI: "generate screenshot" menu item pops up a window with
+ a text area + a radio buttons "text/html". When you flick
+ them, the text area is automatically updated.
+
+- Fixing the oops in kernels < 2.6.11
+
+ - Probably just require 2.6.11 (necessary for timer interrupt
+ based anyway).
+
+ - Make the process waiting in poll() responsible for extracting
+ the backtrace. Give a copy of the entire stack rather than doing
+ the walk inside the kernel.
+
+ New model:
+ - Two arrays,
+ one of actual scanned stacks
+ one of tasks that need to be scanned
+ One wait queue,
+ wait for data
+
+ - in read() wait for stack data:
+ scan_tasks()
+ if (!stack_data)
+ return -EWOULDBLOCK;
+
+ in poll()
+ while (!stack data) {
+ wait_for_data();
+ scan_tasks();
+ }
+ return READABLE;
+
+ scan_tasks() is a function that converts waiting
+ tasks into data, and wakes them up.
+
+ - in timer interrupt:
+
+ if (someone waiting in poll() &&
+ current && current != that_someone &&
+ current is runnable)
+ {
+ stop current;
+ add current to queue;
+ wake wait_for_data;
+ }
+
+ This way, we will have a real userspace process
+ that can take the page faults.
+
+
+ - Different approach:
+
+ pollable file where a regular userspace process
+ can read a pid. Any pid returned is guaranteed to be
+ UNINTERRUPTIBLE. Userspace process is required to
+ start it again when it is done with it.
+
+ Also provide interface to read arbitrary memory of
+ that process.
+
+ ptrace() could in principle do all this, but
+ unfortunately it sucks to continuously
+ ptrace() processes.
+
+ - Yet another
+
+ Userspace process can register itself as "profiler"
+ and pass in a filedescriptor where all sorts of
+ information is sent.
+
+ - could tie lifetime of module to profiler
+ - could send "module going away" information
+ - Can we map filedescriptors to files in
+ a module?
+
+- Find out how gdb does backtraces; they may have a better way. Also
+ find out what dwarf2 is and how to use it. Look into libunwind.
+ It seems gdb is capable of doing backtraces of code that neither has
+ a framepointer nor has debug info. It appears gdb uses the contents
+ of the ".eh_frame" section. There is also an ".eh_frame_hdr" section.
+
+http://www.linuxbase.org/spec/booksets/LSB-Embedded/LSB-Embedded/ehframe.html
+
+ look in dwarf2-frame.[ch] in the gdb distribution.
+
+- Make busy cursors more intelligent
+ - when you click something in the main list and we don't respond
+ within 50ms (or perhaps when we expect to not be able to do
+ so (can we know the size in advance?))
+ - instead of what we do now: set the busy cursor unconditionally
+
+- Reorganise stackstash and profile
+
+ - stackstash should just take traces of addresses without knowing
+ anything about what those addresses mean
+
+ - stacktraces should then begin with a process
+
+ - profile should take traces of pointers to presentation
+ objects without knowing anything about these presentation
+ objects.
+
+ - Creating a profile is then
+
+ - For each stack node, compute a presentation object
+ (probably need to export opaque stacknode objects
+ with set/get_user_data)
+
+ - Send each stack trace to the profile module, along with
+ presentation objects. Maybe just a map from stack nodes
+ to presentation objects.
+
+- Charge 'self' properly to processes that don't get any stack trace at all
+ (probably we get that for free with stackstash reorganisation)
+
+- support more than one reader of the samples properly
+ - Don't generate them if noone cares
+ - When not profiling, sysprof shouldn't care
+
+- Add ability to show more than one function at a time. Algorithm:
+ Find all relevant nodes;
+ For each relevant node
+ best_so_far = relevant node
+ walk towards root
+ if node is relevant,
+ best_so_far = relevant
+ add best_so_far to interesting
+ for each interesting
+ list leaves
+ for each leaf
+ add trace to tree (leaf, interesting)
+- Consider adding KDE-style nested callgraph view
+ - probably need a dependency on gtk+ 2.8 (cairo) for this.
+- Add support for line numbers within functions
+ - Possibly a special "view details" mode, assuming that
+ the details of a function are not that interesting
+ together with a tree.
+- rethink caller list, not terribly useful at the moment. Federico suggested
+ listing all ancestors.
+
+
+- Have kernel module report the file the address was found in
+ Should avoid a lot of potential broken/raciness with dlopen etc.
+- Make things faster
+ - Can I get it to profile itself?
+ - speedprof seems to report that lots of time is spent in
+ stack_stash_foreach() and also in generate_key()
+- add an 'everything' object. It is really needed for a lot of things
+ - should be easy to do with stackstash reorganization.
+
+- Non-GUI version that can save in a format the GUI can understand.
+ Could be used for profiling startup etc. Would preferably be able to
+ dump the data to a network socket. Should be able to react to eg.
+ SIGUSR1 by dumping the data.
+
+ Work done by Lorenzo:
+
+ http://www.colitti.com/lorenzo/software/gnome-startup/sysprof-text.diff
+ http://www.colitti.com/lorenzo/software/gnome-startup/sysprof.log
+ http://colitti.com/lorenzo/software/gnome-startup/
+
+- Figure out how Google's pprof script works. Then add real call graph
+ drawing. (google's script is really simple; uses dot from graphviz).
+
+- hide internal stuff in ProfileDescendant
+
+- possibly add dependency on glib 2.8 if it is released at that point.
+ (g_file_replace())
+
+- somehow get access to VSEnterprise profiler and see how it works.
+ somehow get access to vtune and see how it works.
+
+Later:
+
+- See if it is possible to group the X server activity under the process that
+ generated it.
+
+- .desktop file
+ [Is this worth it? You will often want to start it as root,
+ and you will need to insert the module from the command line]
+- Applications should be able to say "start profiling", "stop profiling"
+ so that you can limit the profiling to specific areas.
+ Idea:
+ Add a new kernel interface that applications uses to say
+ begin/end.
+ Then add a timeline where you can mark interesting regions,
+ for example those that applications have marked interesting.
+
+- Find out how to hack around gtk+ bug causing multiple double clicks
+ to get eaten.
+
+- Consider what it would take to take stacktraces of other languages
+
+ - perl,
+ - python
+ - java
+ - bash
+
+ Possible solution is for the script binaries to have a function
+ called something like
+
+ __sysprof__generate_stacktrace (char **functions, int *n_functions);
+
+ that the sysprof kernel module could call (and make return to the kernel).
+
+ This function would behave essentially like a signal handler: couldn't
+ call malloc(), couldn't call printf(), etc.
+
+ Note thought that scripting languages will generally have a stack with
+ both script-binary-stack, script stack, and library stacks. We wouldn't
+ want scripts to need to parse dwarf. Also if we do that thing with
+ sending the entire stack to userspace, things will be further complicated.
+
+- Consider this usecase:
+ Someone is considering replacing malloc()/free() with a freelist
+ for a certain data structure. All use of this data structure is
+ confined to one function, foo(). It is now interesting to know
+ how much time that particular function spends on malloc() and free()
+ combined.
+
+ Possible UI:
+
+ - Select foo(),
+ - find an instance of malloc()
+ - shift-click on it,
+ - all traces with malloc are removed
+ - a new item "..." appears immeidately below foo()
+ - malloc is added below "..."
+ - same for free
+ - at this point, the desired data can be read at comulative
+ for "..."
+
+ Actually, with this UI, you could potentially get rid of the
+ caller list: Just present the call tree under an <everything> root,
+ and use ... to single out the stuff you are interested in.
+
+ Maybe also get rid of 'callers' by having a new "show details"
+ dialog or something.
+
+ The complete solution here degenerates into "expressions":
+
+ "foo" and ("malloc" or "free")
+
+ Having that would also take care of the "multiple functions"
+ above. Noone would understand it, though.
+
+- figure out a way to deal with both disk and CPU. Need to make sure that
+ things that are UNINTERRUPTIBLE while there are RUNNING tasks are not
+ considered bad. Also figure out how to deal with more than one CPU/core.
+
+ Not entirely clear that the sysprof visualization is right for disk.
+
+ Maybe assign a size of n to traces with n *unique* disk access (ie.
+ disk accesses that are not required by any other stack trace).
+
+ Or assign values to nodes in the calltree based on how many diskaccesses
+ are contained in that tree. Ie., if I get rid of this branch, how many
+ disk accesses would that get rid of.
+
+ Or turn it around and look at individual disk accesses and see what it
+ would take to get rid of it. Ie., a number of traces are associated with
+ any given diskaccess. Just show those.
+
+ Or for a given tree with contained disk accesses, figure out what *other*
+ traces has the same diskaccesses.
+
+ Or visualize a set of squares with a color that is more saturated depending
+ on the number of unique stack traces that access it. Then look for the
+ lightly saturated ones.
+
+ The input to the profiler would basically be
+
+ (stack trace, badness, cookie)
+
+ For CPU: badness=10ms, cookie=<a new one always>
+ For Disk: badness=<calculated based on previous disk accesses>, cookie=<the accessed disk block>
+
+ For Memory: badness=<cache line size not in cache>, cookie=<the address>
+
+ Cookies are used to figure out whether an access is really the same, ie., for two identical
+ cookies, the size is still just one, however
+
+ Memory is different from disk because you can't reasonably assume that stuff that has
+ been read will stay in cache (for short profile runs you can assume that with disk,
+ but not for long ones).
+
+ - Perhaps show a timeline with CPU in one color and disk in one color. Allow people to
+ look at at subintervals of this timeline. Is it useful to look at both CPU and disk at
+ the same time? Probably not. See also marker discussion above. UI should probably allow
+ double clicking on a marked section and all instances of that one would be marked.
+
+ - Other variation on the timeline idea: Instead of a disk timeline you could have a
+ list of individual diskaccesses, and be able to select the ones you wanted to
+ get rid of.
+
+ - The existing sysprof visualization is not terribly bad, the "self" column is
+ more useful now.
+
+ - See what files are accessed so that you can get a getter idea of what
+ the system is doing.
+
+ - Optimization usecases:
+
+ - A lot of stuff is read synchronously, but it is possible to read it asynchronously.
+ Visualization: A timeline with alternating CPU/disk activity.
+
+ - What function is doing all the synchronous reading, and what files/offsets is
+ it reading. Visualization: lots of reads across different files out of one
+ function
+
+ - A piece of the program is doing disk I/O. We can drop that entire piece of
+ code. Sysprof visualization is ok, although seeing the files accessed is useful
+ so that we can tell if those files are not just going to be used in
+ other places. (Gnumeric plugin_init()).
+
+ - A function is reading a file synchronously, but there is other (CPU/disk) stuff
+ that could be done at the same time. Visualization: A piece of the timeline
+ is diskbound with little or no CPU used.
+
+ - Want to improve code locality of library or binary. Visualization: no GUI, just
+ produce a list of functions that should be put first in the file. Then run the
+ program again until the list converges. (Valgrind may be more useful here).
+
+ - Nautilus reads a ton of files, icons + all the files in the homedirectory.
+ Normal sysprof visualization is probably useful enough.
+
+ - Profiling a login session.
+
+ - Need to report stat() as well. (Where do inode data end up? In the buffer-cache?)
+ Also open() may cause disk reads (seeks).
+
+ - To generate the timeline we need to know when a disk request is issued and when it
+ is completed. This way we can assign blame to all applications that have issued a
+ disk request at a given point in time.
+
+ The disk timeline should probably vary in intensity with the number of outstanding
+ disk requests.
+
+DONE:
+
+* consider caching [filename => bin_file]
+
+* Check the kernel we are building against, if it is SMP or
+ less than 2.6.11, print a warning and suggest upgrading.
+
+* Timer interrupt based
+
+* Interface
+ - Consider expanding a few more levels of a new descendants tree
+ - Algorithm should be expand in proportion to the
+ "total" percentage. Basically consider 'total' the
+ likelyhood that the user is going to look at it.
+ - Maybe just; keep expanding the biggest total until
+ there is no more room or we run out of things to expand.
+
+* Web page containing
+
+ - Screen shots
+ - Explanation of what it is
+ - Download
+ - Bug reporting
+ - Contact info
+ - Ask for sucess/failure reports
+- hook up menu items view/start etc (or possibly get rid of them or
+ move them)
+- Should do as suggested in the automake manual in the
+ chapter "when automake is not enough"
+- add an "insert-module" target
+- need to run depmod on install
+- If the current profile has a name, display it in the title bar
+- auto*?
+- Find out if that PREFIX business in Makefile was really such
+ a great idea.
+- Sould just install the kernel module if it running as root, pop up
+ a dialog if not. Note we must be able to start without module now,
+ since it is useful to just load profiles from disk.
+ - Is there a portable way of asking for the root password?
+ - Install a small suid program that only inserts the module?
+ (instant security hole ..)
+- Need to make "make install" work (how do you know where to install
+ kernel modules?)
+ - in /lib/modules/`uname -r`/kernel/drivers/
+ - need to run depmod as root after that
+ - Then modprobe run as root should correctly find it.
+
+- grep FIXME
+
+- give profiles on the command line
+
+- Hopefully the oops at the end of this file is gone now that
+ we use mmput/get_task_mm. For older kernels those symbols
+ are not exported though, so we will probably have to either
+ use the old way (directly accessing the mm's) or just not
+ support those kernels.
+
+- Need an icon
+
+- hook up about box
+
+- Add busy cursors,
+ - when you hit "Profile"
+ - when you click something in the main list and we don't respond
+ within 50ms (or perhaps when we expect to not be able to do
+ so (can we know the size in advance?))
+
+- kernel module should put process to sleep before sampling. Should get us
+ more accurate data
+
+- Make sure samples label shows correct nunber after Open
+
+- Move "samples" label to the toolbar, then get rid of statusbar.
+
+- crashes when you ctrl-click the selected item in the top left pane
+ <ian__> ssp: looks like it doesn't handle the none-selected case
+
+- loading and saving
+
+- consider making ProfileObject more of an object.
+
+- make an "everything" object
+ maybe not necessary -- there is a libc_ctors_something()
+
+- make presentation strings nicer
+
+ four different kinds of symbols:
+
+ a) I know exactly what this is
+ b) I know in what library this is
+ c) I know only the process that did this
+ d) I know the name, but there is another similarly named one
+
+ (a) is easy, (b) should be <in ...> (c) should just become "???"
+ (d) not sure
+
+- processes with a cmdline of "" should get a [pid = %d] instead.
+
+- make an "n samples" label
+Process stuff:
+
+- make threads be reported together
+ (simply report pids with similar command lines together)
+ (note: it seems separating by pid is way too slow (uses too much memory),
+ so it has to be like this)
+
+- stack stash should allow different pids to refer to the same root
+ (ie. there is no need to create a new tree for each pid)
+ The *leaves* should contain the pid, not the root. You could even imagine
+ a set of processes, each referring to a set of leaves.
+
+- when we see a new pid, immediately capture its mappings
+
+Road map:
+ - new object Process
+ - hashable by pointer
+ - contains list of maps
+ - process_from_pid (pid_t pid, gboolean join_threads)
+ - new processes are gets their maps immediately
+ - resulting pointer must be unref()ed, but it is possible it
+ just points to an existing process
+ - processes with identical cmdlines are taken together
+ - method lookup_symbol()
+ - method get_name()
+ - ref/unref
+ - StackStash stores map from process to leaves
+ - Profile is called with processes
+
+It is possible that we simply need a better concept of Process:
+
+ If two pids have the same command line, consider them the same, period.
+ This should save considerable amounts of memory.
+
+ The assumptions:
+
+ "No pids are reused during a profiling run"
+ "Two processes with the same command line have the same mappings"
+
+ are somewhat dubious, but probably necessary.
+
+ (More complex kernel:
+
+ have the module report
+
+ - new pid arrived (along with mappings)
+ - mapping changed for pid
+ - stacktrace)
+
+- make symbols in executable work
+- the hashtables used in profile.c should not accept NULL as the key
+- make callers work
+- autoexpand descendant tree
+- make double clicks work
+- fix leaks
+
+
+- Find out what happened here:
+
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: Unable to handle kernel NULL pointer dereference at virtual address 000001b8
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: printing eip:
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: c017342c
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: *pde = 00000000
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: Oops: 0000 [#1]
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: Modules linked in: sysprof_module(U) i2c_algo_bit md5 ipv6 parport_pc lp parport autofs4 sunrpc video button battery ac ohci1394 ieee1394 uhci_hcd ehci_hcd hw_random tpm_atmel tpm i2c_i801 i2c_core snd_intel8x0 snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd soundcore snd_page_alloc e1000 floppy dm_snapshot dm_zero dm_mirror ext3 jbd dm_mod ata_piix libata sd_mod scsi_mod
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: CPU: 0
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: EIP: 0060:[<c017342c>] Not tainted VLI
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: EFLAGS: 00010287 (2.6.11-1.1225_FC4)
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: EIP is at grab_swap_token+0x35/0x21f
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: eax: 0bd48023 ebx: d831d028 ecx: 00000282 edx: 00000000
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: esi: c1b72934 edi: c1045820 ebp: c1b703f0 esp: c18dbdd8
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: ds: 007b es: 007b ss: 0068
+Apr 11 15:42:08 great-sage-equal-to-heaven kernel: Process events/0 (pid: 3, threadinfo=c18db000 task=f7e62000)
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: Stack: 000011a8 00000000 000011a8 c1b703f0 c0151731 c016f58f 000011a8 c1b72934
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: 000011a8 c0166415 c1b72934 c1b72934 c0163768 ee7ccc38 f459fbf8 bf92e7b8
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: f6c6a934 c0103b92 bfdaba18 c1b703f0 00000001 c1b81bfc c1b72934 bfdaba18
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: Call Trace:
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0151731>] find_get_page+0x9/0x24
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c016f58f>] read_swap_cache_async+0x32/0x83Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0166415>] do_swap_page+0x262/0x600
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0163768>] pte_alloc_map+0xc6/0x1e6
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0103b92>] common_interrupt+0x1a/0x20
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c01673f0>] handle_mm_fault+0x1da/0x31d
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c016488e>] __follow_page+0xa2/0x10d
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0164a6f>] get_user_pages+0x145/0x6ee
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0161f66>] kmap_high+0x52/0x44e
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<c0103b92>] common_interrupt+0x1a/0x20
+Apr 11 15:42:09 great-sage-equal-to-heaven kernel: [<f8cbb19d>] x_access_process_vm+0x111/0x1a5 [sysprof_module]
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<f8cbb24a>] read_user_space+0x19/0x1d [sysprof_module]
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<f8cbb293>] read_frame+0x35/0x51 [sysprof_module]
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<f8cbb33a>] generate_stack_trace+0x8b/0xb4
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<f8cbb3a2>] do_generate+0x3f/0xa0 [sysprof_module]
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c0138d7a>] worker_thread+0x1b0/0x450
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c0379ccd>] schedule+0x30d/0x780
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c011bdb6>] __wake_up_common+0x39/0x59
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<f8cbb363>] do_generate+0x0/0xa0 [sysprof_module]
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c011bd71>] default_wake_function+0x0/0xc
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c0138bca>] worker_thread+0x0/0x450
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c013f3cb>] kthread+0x87/0x8b
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c013f344>] kthread+0x0/0x8b
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: [<c0101275>] kernel_thread_helper+0x5/0xb
+Apr 11 15:42:10 great-sage-equal-to-heaven kernel: Code: e0 8b 00 8b 50 74 8b 1d c4 55 3d c0 39
+da 0f 84 9b 01 00 00 a1 60 fc 3c c0 39 05 30 ec 48 c0 78 05 83 c4 20 5b c3 a1 60 fc 3c c0 <3b> 82 b8 01 00 00 78 ee 81 3d ac 55 3d c0 3c 4b 24 1d 0f 85 78
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..854fe2d
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1019 @@
+# generated automatically by aclocal 1.7.9 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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.
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 10
+
+AC_PREREQ([2.54])
+
+# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
+# the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.7.9])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright 2001, 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# -*- Autoconf -*-
+
+
+# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+# Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_AUX_DIR_EXPAND], [
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# -*- Autoconf -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# serial 5 -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 5
+
+AC_PREREQ(2.52)
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_PREREQ([2.52])
+
+# serial 6
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+#
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists. Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+ if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ else
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+ [pkg_failed=yes])
+ fi
+else
+ pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+ [AC_MSG_RESULT([no])
+ $4])
+elif test $pkg_failed = untried; then
+ ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+ [$4])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
+
diff --git a/binfile.c b/binfile.c
new file mode 100644
index 0000000..dead704
--- /dev/null
+++ b/binfile.c
@@ -0,0 +1,593 @@
+/* MemProf -- memory profiler and leak detector
+ * Copyright 1999, 2000, 2001, Red Hat, Inc.
+ * Copyright 2002, Kristian Rietveld
+ *
+ * Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Most interesting code in this file is lifted from bfdutils.c
+ * and process.c from Memprof,
+ */
+
+#include <glib.h>
+#include "binfile.h"
+#include <bfd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+static void bfd_nonfatal (const char *string);
+static void bfd_fatal (const char *string);
+
+/* Binary File */
+struct BinFile
+{
+ char * filename;
+ int n_symbols;
+ Symbol *symbols;
+ Symbol undefined;
+ int ref_count;
+};
+
+static bfd *
+open_bfd (const char *file)
+{
+ bfd *abfd = bfd_openr (file, NULL);
+
+ if (!abfd)
+ return NULL;
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ bfd_close (abfd);
+ return NULL;
+ }
+
+ return abfd;
+}
+
+static unsigned long
+calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+ static const unsigned long crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+ };
+ unsigned char *end;
+
+ crc = ~crc & 0xffffffff;
+ for (end = buf + len; buf < end; ++buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc & 0xffffffff;;
+}
+
+static char *
+get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+{
+ asection *sect;
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ char *contents;
+ int crc_offset;
+
+ sect = bfd_get_section_by_name (abfd, ".gnu_debuglink");
+
+ if (sect == NULL)
+ return NULL;
+
+ debuglink_size = bfd_section_size (abfd, sect);
+
+ contents = g_malloc (debuglink_size);
+ bfd_get_section_contents (abfd, sect, contents,
+ (file_ptr)0, (bfd_size_type)debuglink_size);
+
+ /* Crc value is stored after the filename, aligned up to 4 bytes. */
+ crc_offset = strlen (contents) + 1;
+ crc_offset = (crc_offset + 3) & ~3;
+
+ crc32 = bfd_get_32 (abfd, (bfd_byte *) (contents + crc_offset));
+
+ *crc32_out = crc32;
+ return contents;
+}
+
+static gboolean
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+ unsigned long file_crc = 0;
+ int fd;
+ guchar buffer[8*1024];
+ int count;
+
+ fd = open (name, O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+ file_crc = calc_crc32 (file_crc, buffer, count);
+
+ close (fd);
+
+ if (crc != file_crc)
+ {
+ g_print ("warning: %s has wrong crc\n", name);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+/* FIXME - not10: this should probably be detected by config.h -- find out what gdb does*/
+static const char *debug_file_directory = "/usr/lib/debug";
+
+static char *
+find_separate_debug_file (bfd *abfd)
+{
+ char *basename;
+ char *dir;
+ char *debugfile;
+ unsigned long crc32;
+
+ basename = get_debug_link_info (abfd, &crc32);
+ if (basename == NULL)
+ return NULL;
+
+ dir = g_path_get_dirname (bfd_get_filename (abfd));
+
+ /* First try in the same directory as the original file: */
+ debugfile = g_build_filename (dir, basename, NULL);
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ g_free (basename);
+ g_free (dir);
+ return debugfile;
+ }
+ g_free (debugfile);
+
+ /* Then try in a subdirectory called .debug */
+ debugfile = g_build_filename (dir, ".debug", basename, NULL);
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ g_free (basename);
+ g_free (dir);
+ return debugfile;
+ }
+ g_free (debugfile);
+
+ /* Then try in the global debugfile directory */
+ debugfile = g_build_filename (debug_file_directory, dir, basename, NULL);
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ g_free (basename);
+ g_free (dir);
+ return debugfile;
+ }
+ g_free (debugfile);
+
+ g_free (basename);
+ g_free (dir);
+ return NULL;
+}
+
+static asymbol **
+slurp_symtab (bfd *abfd, long *symcount)
+{
+ asymbol **sy = (asymbol **) NULL;
+ long storage;
+
+ if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+ {
+ *symcount = 0;
+ return NULL;
+ }
+
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ if (storage)
+ sy = (asymbol **) malloc (storage);
+
+ *symcount = bfd_canonicalize_symtab (abfd, sy);
+ if (*symcount < 0)
+ bfd_fatal (bfd_get_filename (abfd));
+
+ return sy;
+}
+
+extern char *cplus_demangle (const char *mangled, int options);
+
+#define DMGL_PARAMS (1 << 0) /* Include function args */
+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+
+static char *
+demangle (bfd *bfd, const char *name)
+{
+ char *demangled;
+
+ if (bfd_get_symbol_leading_char (bfd) == *name)
+ ++name;
+
+ demangled = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ return demangled ? demangled : g_strdup (name);
+}
+
+static gint
+compare_address (const void *a, const void *b)
+{
+ const Symbol *symbol1 = a;
+ const Symbol *symbol2 = b;
+
+ if (symbol1->address < symbol2->address)
+ return -1;
+ else if (symbol1->address == symbol2->address)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+read_symbols (BinFile *bf)
+{
+ asection *text_section;
+ const char *separate_debug_file;
+ asymbol **bfd_symbols;
+ long n_symbols;
+ int i;
+ bfd *bfd;
+ GArray *symbols;
+ file_ptr real_text_offset;
+
+ bf->symbols = NULL;
+ bf->n_symbols = 0;
+
+ bfd = open_bfd (bf->filename);
+ if (!bfd)
+ return;
+
+ text_section = bfd_get_section_by_name (bfd, ".text");
+ if (!text_section)
+ {
+ bfd_close (bfd);
+ return;
+ }
+
+ /* Offset of the text segment in the real binary (not the debug one) */
+ real_text_offset = text_section->filepos;
+
+ separate_debug_file = find_separate_debug_file (bfd);
+ if (separate_debug_file)
+ {
+ bfd_close (bfd);
+ bfd = open_bfd (separate_debug_file);
+#if 0
+ g_print ("bfd for %s is %s\n", bf->filename, separate_debug_file);
+#endif
+ if (!bfd)
+ return;
+ }
+
+ bfd_symbols = slurp_symtab (bfd, &n_symbols);
+
+ if (!bfd_symbols)
+ return;
+
+ text_section = bfd_get_section_by_name (bfd, ".text");
+ if (!text_section)
+ return;
+
+ symbols = g_array_new (FALSE, FALSE, sizeof (Symbol));
+
+ /* g_print ("%s: text vma: %x\n", bf->filename, text_section->vma); */
+
+ for (i = 0; i < n_symbols; i++)
+ {
+ Symbol symbol;
+
+ if ((bfd_symbols[i]->flags & BSF_FUNCTION) &&
+ (bfd_symbols[i]->section == text_section))
+ {
+ /* Store the address in
+ *
+ * "offset into text_segment + filepos of text segment in original binary"
+ *
+ * Ie., "file position of original binary"
+ */
+
+ /* offset into text section */
+ symbol.address =
+ bfd_asymbol_value (bfd_symbols[i]) - text_section->vma + real_text_offset;
+
+ symbol.name = demangle (bfd, bfd_asymbol_name (bfd_symbols[i]));
+#if 0
+ g_print ("computed address for %s: %lx\n", symbol.name, symbol.address);
+#endif
+ g_array_append_vals (symbols, &symbol, 1);
+ }
+ }
+
+ if (n_symbols)
+ free (bfd_symbols);
+
+#if 0
+ if (!n_symbols)
+ g_print ("no symbols found for %s\n", bf->filename);
+ else
+ g_print ("symbols found for %s\n", bf->filename);
+#endif
+
+ /* Sort the symbols by address */
+ qsort (symbols->data, symbols->len, sizeof(Symbol), compare_address);
+
+ bf->n_symbols = symbols->len;
+ bf->symbols = (Symbol *)g_array_free (symbols, FALSE);
+}
+
+static GHashTable *bin_files;
+
+BinFile *
+bin_file_new (const char *filename)
+{
+ BinFile *bf;
+
+ if (!bin_files)
+ bin_files = g_hash_table_new (g_str_hash, g_str_equal);
+
+ bf = g_hash_table_lookup (bin_files, filename);
+ if (bf)
+ {
+ bf->ref_count++;
+ }
+ else
+ {
+ bf = g_new0 (BinFile, 1);
+
+ bf->filename = g_strdup (filename);
+
+ read_symbols (bf);
+
+ bf->undefined.name = g_strdup_printf ("In file %s", filename);
+ bf->undefined.address = 0x0;
+ bf->ref_count = 1;
+ g_hash_table_insert (bin_files, bf->filename, bf);
+ }
+
+ return bf;
+}
+
+void
+bin_file_free (BinFile *bf)
+{
+ if (--bf->ref_count == 0)
+ {
+ int i;
+
+ g_hash_table_remove (bin_files, bf->filename);
+
+ g_free (bf->filename);
+
+ for (i = 0; i < bf->n_symbols; ++i)
+ g_free (bf->symbols[i].name);
+ g_free (bf->symbols);
+ g_free (bf->undefined.name);
+ g_free (bf);
+ }
+}
+
+/**
+ * bin_file_lookup_symbol:
+ * @bf: A BinFile
+ * @address: The address to lookup
+ *
+ * Look up a symbol. @address should be in file coordinates
+ *
+ **/
+const Symbol *
+bin_file_lookup_symbol (BinFile *bf,
+ gulong address)
+{
+ int first = 0;
+ int last = bf->n_symbols - 1;
+ int middle = last;
+ Symbol *data;
+ Symbol *result;
+
+ if (!bf->symbols || (bf->n_symbols == 0))
+ return &(bf->undefined);
+
+ data = bf->symbols;
+
+#if 0
+ g_print ("looking up %p in %s ", address, bf->filename);
+#endif
+
+ if (address < data[last].address)
+ {
+ /* Invariant: data[first].addr <= val < data[last].addr */
+
+ while (first < last - 1)
+ {
+ middle = (first + last) / 2;
+ if (address < data[middle].address)
+ last = middle;
+ else
+ first = middle;
+ }
+ /* Size is not included in generic bfd data, so we
+ * ignore it for now. (It is ELF specific)
+ */
+ result = &data[first];
+ }
+ else
+ {
+ result = &data[last];
+ }
+
+#if 0
+ g_print ("-> %s\n", result->name);
+#endif
+
+ /* If the name is "call_gmon_start", the file probably doesn't
+ * have any other symbols
+ */
+ if (strcmp (result->name, "call_gmon_start") == 0)
+ return &(bf->undefined);
+ else if (strncmp (result->name, "__do_global_ctors_aux", strlen ("__do_global_ctors_aux")) == 0)
+ {
+#if 0
+ g_print ("ctors: %p, pos: %p\n", address, result->address);
+#endif
+ }
+
+ return result;
+}
+
+
+/* Symbol */
+Symbol *
+symbol_copy (const Symbol *orig)
+{
+ Symbol *copy;
+
+ copy = g_new (Symbol, 1);
+ copy->name = g_strdup (orig->name);
+ copy->address = orig->address;
+
+ return copy;
+}
+
+gboolean
+symbol_equal (const void *sa,
+ const void *sb)
+{
+ const Symbol *syma = sa;
+ const Symbol *symb = sb;
+
+ if (symb->address != syma->address)
+ return FALSE;
+
+ /* symbols compare equal if their names are both NULL */
+
+ if (!syma->name && !symb->name)
+ return TRUE;
+
+ if (!syma)
+ return FALSE;
+
+ if (!symb)
+ return FALSE;
+
+ return strcmp (syma->name, symb->name) == 0;
+}
+
+guint
+symbol_hash (const void *s)
+{
+ const Symbol *symbol = s;
+
+ if (!s)
+ return 0;
+
+ return symbol->name? g_str_hash (symbol->name) : 0 + symbol->address;
+}
+
+void
+symbol_free (Symbol *symbol)
+{
+ if (symbol->name)
+ g_free (symbol->name);
+ g_free (symbol);
+}
+
+static void
+bfd_nonfatal (const char *string)
+{
+ const char *errmsg = bfd_errmsg (bfd_get_error ());
+
+ if (string)
+ {
+ fprintf (stderr, "%s: %s: %s\n",
+ g_get_application_name(), string, errmsg);
+ }
+ else
+ {
+ fprintf (stderr, "%s: %s\n",
+ g_get_application_name(), errmsg);
+ }
+}
+
+static void
+bfd_fatal (const char *string)
+{
+ bfd_nonfatal (string);
+ exit (1);
+}
diff --git a/binfile.h b/binfile.h
new file mode 100644
index 0000000..f26b15b
--- /dev/null
+++ b/binfile.h
@@ -0,0 +1,52 @@
+/* MemProf -- memory profiler and leak detector
+ * Copyright 1999, 2000, 2001, Red Hat, Inc.
+ * Copyright 2002, Kristian Rietveld
+ *
+ * Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef BIN_FILE_H
+#define BIN_FILE_H
+
+#include <glib.h>
+
+typedef struct BinFile BinFile;
+typedef struct Symbol Symbol;
+
+/* Binary File */
+
+BinFile * bin_file_new (const char *filename);
+void bin_file_free (BinFile *bin_file);
+const Symbol *bin_file_lookup_symbol (BinFile *bin_file,
+ gulong address);
+
+/* Symbol */
+struct Symbol
+{
+ char * name;
+ gulong address;
+};
+
+Symbol * symbol_copy (const Symbol *orig);
+gboolean symbol_equal (const void *syma,
+ const void *symb);
+guint symbol_hash (const void *sym);
+void symbol_free (Symbol *symbol);
+
+#endif
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..0202b14
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,22 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Look for global separate debug info in this path */
+#undef DEBUGDIR
+
+/* Define to 1 if you have the `iberty' library (-liberty). */
+#undef HAVE_LIBIBERTY
+
+/* 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
diff --git a/configure b/configure
new file mode 100755
index 0000000..d1c7ac0
--- /dev/null
+++ b/configure
@@ -0,0 +1,4750 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for sysprof 1.0.7.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='sysprof'
+PACKAGE_TARNAME='sysprof'
+PACKAGE_VERSION='1.0.7'
+PACKAGE_STRING='sysprof 1.0.7'
+PACKAGE_BUGREPORT=''
+
+ac_unique_file="sysprof.glade"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE PKG_CONFIG ac_pt_PKG_CONFIG DEP_CFLAGS DEP_LIBS MODULE_SUBDIR LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_cv_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_cv_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_env_DEP_CFLAGS_set=${DEP_CFLAGS+set}
+ac_env_DEP_CFLAGS_value=$DEP_CFLAGS
+ac_cv_env_DEP_CFLAGS_set=${DEP_CFLAGS+set}
+ac_cv_env_DEP_CFLAGS_value=$DEP_CFLAGS
+ac_env_DEP_LIBS_set=${DEP_LIBS+set}
+ac_env_DEP_LIBS_value=$DEP_LIBS
+ac_cv_env_DEP_LIBS_set=${DEP_LIBS+set}
+ac_cv_env_DEP_LIBS_value=$DEP_LIBS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures sysprof 1.0.7 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of sysprof 1.0.7:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors
+ --disable-kernel-module disable building kernel module
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-separate-debug-dir=path Look for global separate debug info in this path LIBDIR/debug
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ PKG_CONFIG path to pkg-config utility
+ DEP_CFLAGS C compiler flags for DEP, overriding pkg-config
+ DEP_LIBS linker flags for DEP, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+sysprof configure 1.0.7
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by sysprof $as_me 1.0.7, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+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 || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+am__api_version="1.7"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+ # test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='sysprof'
+ VERSION='1.0.7'
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+
+
+
+
+ ac_config_headers="$ac_config_headers config.h"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+if test "x$GCC" = "xyes"; then
+ case " $CFLAGS " in
+ *[\ \ ]-Wall[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wall" ;;
+ esac
+fi
+
+debugdir=${libdir}/debug
+
+# Separate debug dir
+
+
+
+
+
+# Check whether --with-separate-debug-dir or --without-separate-debug-dir was given.
+if test "${with_separate_debug_dir+set}" = set; then
+ withval="$with_separate_debug_dir"
+ debugdir="${withval}"
+fi;
+
+
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo $debugdir`
+ ac_define_dir=`eval echo $ac_define_dir`
+
+cat >>confdefs.h <<_ACEOF
+#define DEBUGDIR "$ac_define_dir"
+_ACEOF
+
+
+
+# Check whether --enable-kernel-module or --disable-kernel-module was given.
+if test "${enable_kernel_module+set}" = set; then
+ enableval="$enable_kernel_module"
+
+fi;
+
+kernel_module="yes"
+if test "x$enableval" = "xno"; then
+ kernel_module="no"
+fi
+
+if test $kernel_module = "yes"; then
+ # Activate build in module/ subdir
+ MODULE_SUBDIR=module
+
+ # Kernel version
+ KMAJOR=`uname -r | cut -d"." -f 1`
+ KMINOR=`uname -r | cut -d"." -f 2`
+ KMICRO=`uname -r | cut -d"." -f 3 | cut -d"-" -f 1`
+
+ if [ $KMICRO -lt 11 ] ; then
+ echo \*
+ echo \* Linux \>= 2.6.11 is required
+ echo \*
+ exit 1
+ fi
+
+ if ! test -f /lib/modules/`uname -r`/build/Makefile ; then
+ echo \*
+ echo \* Sysprof requires the kernel source code to be installed.
+ echo \* On a Fedora Core system the relevant package is kernel-devel
+ echo \*
+ exit 1
+ fi
+fi
+
+# Pkgconfig dependencies
+
+dep_modules="gtk+-2.0 > 2.6.0 gthread-2.0 gdk-pixbuf-2.0 pangoft2 libglade-2.0"
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+
+if test -n "$PKG_CONFIG"; then
+ echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
+echo "${ECHO_T}$PKG_CONFIG" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+
+if test -n "$ac_pt_PKG_CONFIG"; then
+ echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5
+echo "${ECHO_T}$ac_pt_PKG_CONFIG" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5
+echo $ECHO_N "checking pkg-config is at least version $_pkg_min_version... $ECHO_C" >&6
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ PKG_CONFIG=""
+ fi
+
+fi
+
+pkg_failed=no
+echo "$as_me:$LINENO: checking for DEP" >&5
+echo $ECHO_N "checking for DEP... $ECHO_C" >&6
+
+if test -n "$PKG_CONFIG"; then
+ if test -n "$DEP_CFLAGS"; then
+ pkg_cv_DEP_CFLAGS="$DEP_CFLAGS"
+ else
+ if test -n "$PKG_CONFIG" && \
+ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"\$dep_modules\"") >&5
+ ($PKG_CONFIG --exists --print-errors "$dep_modules") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ pkg_cv_DEP_CFLAGS=`$PKG_CONFIG --cflags "$dep_modules" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ fi
+else
+ pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+ if test -n "$DEP_LIBS"; then
+ pkg_cv_DEP_LIBS="$DEP_LIBS"
+ else
+ if test -n "$PKG_CONFIG" && \
+ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"\$dep_modules\"") >&5
+ ($PKG_CONFIG --exists --print-errors "$dep_modules") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ pkg_cv_DEP_LIBS=`$PKG_CONFIG --libs "$dep_modules" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ fi
+else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ DEP_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$dep_modules"`
+ else
+ DEP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$dep_modules"`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$DEP_PKG_ERRORS" >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ { { echo "$as_me:$LINENO: error: sysprof dependencies not satisfied" >&5
+echo "$as_me: error: sysprof dependencies not satisfied" >&2;}
+ { (exit 1); exit 1; }; }
+elif test $pkg_failed = untried; then
+ { { echo "$as_me:$LINENO: error: sysprof dependencies not satisfied" >&5
+echo "$as_me: error: sysprof dependencies not satisfied" >&2;}
+ { (exit 1); exit 1; }; }
+else
+ DEP_CFLAGS=$pkg_cv_DEP_CFLAGS
+ DEP_LIBS=$pkg_cv_DEP_LIBS
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ :
+fi
+
+# libiberty and libbfd
+
+echo "$as_me:$LINENO: checking for cplus_demangle in -liberty" >&5
+echo $ECHO_N "checking for cplus_demangle in -liberty... $ECHO_C" >&6
+if test "${ac_cv_lib_iberty_cplus_demangle+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-liberty $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cplus_demangle ();
+int
+main ()
+{
+cplus_demangle ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_iberty_cplus_demangle=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iberty_cplus_demangle=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iberty_cplus_demangle" >&5
+echo "${ECHO_T}$ac_cv_lib_iberty_cplus_demangle" >&6
+if test $ac_cv_lib_iberty_cplus_demangle = yes; then
+ :
+else
+
+echo "$as_me:$LINENO: checking for cplus_demangle_opname in -liberty" >&5
+echo $ECHO_N "checking for cplus_demangle_opname in -liberty... $ECHO_C" >&6
+if test "${ac_cv_lib_iberty_cplus_demangle_opname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-liberty -ldl $LIBS"
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cplus_demangle_opname ();
+int
+main ()
+{
+cplus_demangle_opname ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_iberty_cplus_demangle_opname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iberty_cplus_demangle_opname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iberty_cplus_demangle_opname" >&5
+echo "${ECHO_T}$ac_cv_lib_iberty_cplus_demangle_opname" >&6
+if test $ac_cv_lib_iberty_cplus_demangle_opname = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBIBERTY 1
+_ACEOF
+
+ LIBS="-liberty $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: libiberty is required to compile sysprof" >&5
+echo "$as_me: error: libiberty is required to compile sysprof" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+
+
+echo "$as_me:$LINENO: checking for bfd_get_error in -lbfd" >&5
+echo $ECHO_N "checking for bfd_get_error in -lbfd... $ECHO_C" >&6
+if test "${ac_cv_lib_bfd_bfd_get_error+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbfd -liberty $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char bfd_get_error ();
+int
+main ()
+{
+bfd_get_error ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_bfd_bfd_get_error=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bfd_bfd_get_error=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bfd_bfd_get_error" >&5
+echo "${ECHO_T}$ac_cv_lib_bfd_bfd_get_error" >&6
+if test $ac_cv_lib_bfd_bfd_get_error = yes; then
+ DEP_LIBS="$DEP_LIBS -lbfd -liberty"
+else
+ { { echo "$as_me:$LINENO: error: libbfd is required to compile sysprof" >&5
+echo "$as_me: error: libbfd is required to compile sysprof" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+# emit files
+
+
+
+
+ ac_config_files="$ac_config_files Makefile"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by sysprof $as_me 1.0.7, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -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
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+sysprof config.status 1.0.7
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@PKG_CONFIG@,$PKG_CONFIG,;t t
+s,@ac_pt_PKG_CONFIG@,$ac_pt_PKG_CONFIG,;t t
+s,@DEP_CFLAGS@,$DEP_CFLAGS,;t t
+s,@DEP_LIBS@,$DEP_LIBS,;t t
+s,@MODULE_SUBDIR@,$MODULE_SUBDIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..225105d
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,107 @@
+AC_PREREQ(2.54)
+
+AC_INIT([sysprof], [1.0.7])
+AC_CONFIG_SRCDIR(sysprof.glade)
+
+AM_INIT_AUTOMAKE(no-define)
+
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_PROG_INSTALL
+
+changequote(,)dnl
+if test "x$GCC" = "xyes"; then
+ case " $CFLAGS " in
+ *[\ \ ]-Wall[\ \ ]*) ;;
+ *) CFLAGS="$CFLAGS -Wall" ;;
+ esac
+fi
+changequote([,])dnl
+
+debugdir=${libdir}/debug
+
+# Separate debug dir
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+ ac_define_dir=`eval echo [$]$2`
+ ac_define_dir=`eval echo [$]ac_define_dir`
+ ifelse($3, ,
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+ AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
+AC_ARG_WITH(separate-debug-dir,
+[ --with-separate-debug-dir=path Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+
+AC_DEFINE_DIR(DEBUGDIR, debugdir,
+ [Look for global separate debug info in this path])
+
+AC_ARG_ENABLE(kernel-module,
+ AC_HELP_STRING(--disable-kernel-module, disable building kernel module))
+
+kernel_module="yes"
+if test "x$enableval" = "xno"; then
+ kernel_module="no"
+fi
+
+if test $kernel_module = "yes"; then
+ # Activate build in module/ subdir
+ MODULE_SUBDIR=module
+
+ # Kernel version
+ KMAJOR=`uname -r | cut -d"." -f 1`
+ KMINOR=`uname -r | cut -d"." -f 2`
+ KMICRO=`uname -r | cut -d"." -f 3 | cut -d"-" -f 1`
+
+ if [[ $KMICRO -lt 11 ]] ; then
+ echo \*
+ echo \* Linux \>= 2.6.11 is required
+ echo \*
+ exit 1
+ fi
+
+ if [ ! test -f /lib/modules/`uname -r`/build/Makefile ] ; then
+ echo \*
+ echo \* Sysprof requires the kernel source code to be installed.
+ echo \* On a Fedora Core system the relevant package is kernel-devel
+ echo \*
+ exit 1
+ fi
+fi
+
+# Pkgconfig dependencies
+
+dep_modules="gtk+-2.0 > 2.6.0 gthread-2.0 gdk-pixbuf-2.0 pangoft2 libglade-2.0"
+
+PKG_CHECK_MODULES(DEP, $dep_modules, [],
+ AC_MSG_ERROR([sysprof dependencies not satisfied]))
+
+# libiberty and libbfd
+
+AC_CHECK_LIB(iberty, cplus_demangle,:,
+ AC_CHECK_LIB(iberty, cplus_demangle_opname, [],
+ AC_MSG_ERROR([libiberty is required to compile sysprof]), -ldl))
+
+AC_CHECK_LIB(bfd, bfd_get_error, [DEP_LIBS="$DEP_LIBS -lbfd -liberty"],
+ AC_MSG_ERROR([libbfd is required to compile sysprof]),
+ -liberty)
+
+
+# emit files
+
+AC_SUBST(DEP_LIBS)
+AC_SUBST(MODULE_SUBDIR)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..edb5d38
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,479 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, 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 Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+ base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+ dir=`echo "$object" | sed 's,/.*$,/,'`
+ if test "$dir" = "$object"; then
+ dir=
+ fi
+ # FIXME: should be _deps on DOS.
+ depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6ce63b9
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd=$cpprog
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "$0: no input file specified" >&2
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d "$dst" ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "$0: $src does not exist" >&2
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "$0: no destination specified" >&2
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d "$dst" ]
+ then
+ dst=$dst/`basename "$src"`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp=$pathcomp$1
+ shift
+
+ if [ ! -d "$pathcomp" ] ;
+ then
+ $mkdirprog "$pathcomp"
+ else
+ :
+ fi
+
+ pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd "$dst" &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ dstfile=`basename "$dst" $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename "$dst"`
+ else
+ :
+ fi
+
+# Make a couple of temp file names in the proper directory.
+
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+# Trap to clean up temp files at exit.
+
+ trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+ trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location. We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons. In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+ if [ -f "$dstdir/$dstfile" ]
+ then
+ $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+ $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+ {
+ echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+ (exit 1); exit
+ }
+ else
+ :
+ fi
+} &&
+
+# Now rename the file to the real destination.
+
+ $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+ (exit 0); exit
+}
diff --git a/missing b/missing
new file mode 100755
index 0000000..fc54c64
--- /dev/null
+++ b/missing
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, 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.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing 0.4 - GNU automake"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+ # We have makeinfo, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ fi
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..d2d5f21
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage" 1>&2
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+case $dirmode in
+ '')
+ if mkdir -p -- . 2>/dev/null; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/module/Makefile b/module/Makefile
new file mode 100644
index 0000000..850c896
--- /dev/null
+++ b/module/Makefile
@@ -0,0 +1,72 @@
+ifneq ($(KERNELRELEASE),)
+
+obj-m := sysprof-module.o
+CFLAGS += $(MODCFLAGS) -DKERNEL26
+
+else
+
+ifeq ($(PREFIX),)
+PREFIX := /usr/local
+endif
+
+MODULE := sysprof-module
+KDIR := /lib/modules/$(shell uname -r)/build
+INCLUDE := -isystem $(KDIR)/include
+MODCFLAGS := -DMODULE -D__KERNEL__ -Wall ${INCLUDE}
+
+KMAKE := $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)
+
+modules: $(MODULE).o
+
+insert_module: install
+ modprobe -r sysprof-module
+ modprobe sysprof-module
+
+ifneq ($(shell (uname -r | grep 2.6) > /dev/null ; echo -n $$?),0)
+ echo A 2.6 kernel is required; exit 1
+endif
+
+# build module
+
+$(MODULE).o: $(MODULE).c
+ $(KMAKE) modules
+
+
+# Automake rules, as per "Third-Party Makefiles" in the automake manual
+
+all: $(MODULE).o
+
+distdir:
+ cp sysprof-module.c $(distdir)
+ cp sysprof-module.h $(distdir)
+ cp Makefile $(distdir)
+
+install:
+ $(KMAKE) modules_install
+ [ -e /sbin/depmod ] && /sbin/depmod
+
+install-data:
+install-exec:
+uninstall:
+
+install-info:
+installdirs:
+check:
+installcheck:
+mostlyclean:
+clean:
+ rm -f sysprof-module.ko
+ rm -f sysprof-module.o
+ rm -f sysprof-module.mod.o
+ rm -f sysprof-module.mod.c
+distclean: clean
+maintainer-clean:
+dvi:
+pdf:
+info:
+html:
+tags:
+ctags:
+
+endif
+
diff --git a/module/sysprof-module.c b/module/sysprof-module.c
new file mode 100644
index 0000000..698a8c0
--- /dev/null
+++ b/module/sysprof-module.c
@@ -0,0 +1,267 @@
+/* -*- c-basic-offset: 8 -*- */
+
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef CONFIG_SMP
+# define __SMP__
+#endif
+#include <asm/atomic.h>
+#include <linux/kernel.h> /* Needed for KERN_ALERT */
+#include <linux/module.h> /* Needed by all modules */
+#include <linux/sched.h>
+
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/poll.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/profile.h>
+
+#include "sysprof-module.h"
+
+#include "../config.h"
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+#include <linux/config.h>
+#endif
+
+#if !CONFIG_PROFILING
+# error Sysprof needs a kernel with profiling support compiled in.
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
+# error Sysprof needs a Linux 2.6.11 kernel or later
+#endif
+#include <linux/kallsyms.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Soeren Sandmann (sandmann@daimi.au.dk)");
+
+#define SAMPLES_PER_SECOND (200)
+#define INTERVAL ((HZ <= SAMPLES_PER_SECOND)? 1 : (HZ / SAMPLES_PER_SECOND))
+#define N_TRACES 256
+
+static SysprofStackTrace stack_traces[N_TRACES];
+static SysprofStackTrace * head = &stack_traces[0];
+static SysprofStackTrace * tail = &stack_traces[0];
+DECLARE_WAIT_QUEUE_HEAD (wait_for_trace);
+DECLARE_WAIT_QUEUE_HEAD (wait_for_exit);
+
+/* Macro the names of the registers that are used on each architecture */
+#if defined(CONFIG_X86_64)
+# define REG_FRAME_PTR rbp
+# define REG_INS_PTR rip
+# define REG_STACK_PTR rsp
+#elif defined(CONFIG_X86)
+# define REG_FRAME_PTR ebp
+# define REG_INS_PTR eip
+# define REG_STACK_PTR esp
+#else
+# error Sysprof only supports the i386 and x86-64 architectures
+#endif
+
+typedef struct userspace_reader userspace_reader;
+struct userspace_reader
+{
+ struct task_struct *task;
+ unsigned long cache_address;
+ unsigned long *cache;
+};
+
+typedef struct StackFrame StackFrame;
+struct StackFrame {
+ unsigned long next;
+ unsigned long return_address;
+};
+
+struct work_struct work;
+
+static int
+read_frame (void *frame_pointer, StackFrame *frame)
+{
+#if 0
+ /* This is commented out because we seem to be called with
+ * (current_thread_info()->addr_limit.seg)) == 0
+ * which means access_ok() _always_ fails.
+ *
+ * Not sure why (or if) this isn't the case for oprofile
+ */
+ if (!access_ok(VERIFY_READ, frame_pointer, sizeof(StackFrame)))
+ return 1;
+#endif
+
+ if (__copy_from_user_inatomic (
+ frame, frame_pointer, sizeof (StackFrame)))
+ return 2;
+
+ return 0;
+}
+
+DEFINE_PER_CPU(int, n_samples);
+
+static int
+timer_notify (struct pt_regs *regs)
+{
+ SysprofStackTrace *trace = head;
+ int i;
+ int is_user;
+ static atomic_t in_timer_notify = ATOMIC_INIT(1);
+
+ if ((++get_cpu_var(n_samples) % INTERVAL) != 0)
+ return 0;
+
+ /* 0: locked, 1: unlocked */
+
+ if (!atomic_dec_and_test(&in_timer_notify))
+ goto out;
+
+ is_user = user_mode(regs);
+
+ if (!current || current->pid == 0)
+ goto out;
+
+ if (is_user && current->state != TASK_RUNNING)
+ goto out;
+
+ if (!is_user)
+ {
+ /* kernel */
+
+ trace->pid = current->pid;
+ trace->truncated = 0;
+ trace->n_addresses = 1;
+
+ /* 0x1 is taken by sysprof to mean "in kernel" */
+ trace->addresses[0] = (void *)0x1;
+ }
+ else
+ {
+ StackFrame *frame_pointer;
+ StackFrame frame;
+ memset(trace, 0, sizeof (SysprofStackTrace));
+
+ trace->pid = current->pid;
+ trace->truncated = 0;
+
+ i = 0;
+
+ trace->addresses[i++] = (void *)regs->REG_INS_PTR;
+
+ frame_pointer = (void *)regs->REG_FRAME_PTR;
+
+ while (read_frame (frame_pointer, &frame) == 0 &&
+ i < SYSPROF_MAX_ADDRESSES &&
+ (unsigned long)frame_pointer >= regs->REG_STACK_PTR)
+ {
+ trace->addresses[i++] = (void *)frame.return_address;
+ frame_pointer = (StackFrame *)frame.next;
+ }
+
+ trace->n_addresses = i;
+
+ if (i == SYSPROF_MAX_ADDRESSES)
+ trace->truncated = 1;
+ else
+ trace->truncated = 0;
+ }
+
+ if (head++ == &stack_traces[N_TRACES - 1])
+ head = &stack_traces[0];
+
+ wake_up (&wait_for_trace);
+
+out:
+ atomic_inc(&in_timer_notify);
+ return 0;
+}
+
+static int
+procfile_read(char *buffer,
+ char **buffer_location,
+ off_t offset,
+ int buffer_len,
+ int *eof,
+ void *data)
+{
+ if (head == tail)
+ return -EWOULDBLOCK;
+
+ *buffer_location = (char *)tail;
+
+ BUG_ON(tail->pid == 0);
+
+ if (tail++ == &stack_traces[N_TRACES - 1])
+ tail = &stack_traces[0];
+
+ return sizeof (SysprofStackTrace);
+}
+
+struct proc_dir_entry *trace_proc_file;
+static unsigned int
+procfile_poll(struct file *filp, poll_table *poll_table)
+{
+ if (head != tail)
+ return POLLIN | POLLRDNORM;
+
+ poll_wait(filp, &wait_for_trace, poll_table);
+
+ if (head != tail)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+int
+init_module(void)
+{
+ static struct file_operations fops;
+
+ trace_proc_file =
+ create_proc_entry ("sysprof-trace", S_IFREG | S_IRUGO, &proc_root);
+
+ if (!trace_proc_file)
+ return 1;
+
+ fops = *trace_proc_file->proc_fops;
+ fops.poll = procfile_poll;
+
+ trace_proc_file->read_proc = procfile_read;
+ trace_proc_file->proc_fops = &fops;
+ trace_proc_file->size = sizeof (SysprofStackTrace);
+
+ register_timer_hook (timer_notify);
+
+ printk(KERN_ALERT "sysprof: loaded (%s)\n", PACKAGE_VERSION);
+
+ return 0;
+}
+
+void
+cleanup_module(void)
+{
+ unregister_timer_hook (timer_notify);
+
+ remove_proc_entry("sysprof-trace", &proc_root);
+
+ printk(KERN_ALERT "sysprof: unloaded\n");
+}
+
diff --git a/module/sysprof-module.h b/module/sysprof-module.h
new file mode 100644
index 0000000..66a11ae
--- /dev/null
+++ b/module/sysprof-module.h
@@ -0,0 +1,37 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SYSPROF_MODULE_H
+#define SYSPROF_MODULE_H
+
+typedef struct SysprofStackTrace SysprofStackTrace;
+
+#define SYSPROF_MAX_ADDRESSES 512
+
+struct SysprofStackTrace
+{
+ int pid; /* -1 if in kernel */
+ int truncated;
+ int n_addresses; /* note: this can be 1 if the process was compiled
+ * with -fomit-frame-pointer or is otherwise weird
+ */
+ void *addresses[SYSPROF_MAX_ADDRESSES];
+};
+
+#endif
diff --git a/process.c b/process.c
new file mode 100644
index 0000000..e0a6fa2
--- /dev/null
+++ b/process.c
@@ -0,0 +1,444 @@
+/* MemProf -- memory profiler and leak detector
+ * Copyright 1999, 2000, 2001, Red Hat, Inc.
+ * Copyright 2002, Kristian Rietveld
+ *
+ * Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004-2005 Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "process.h"
+#include "binfile.h"
+
+#define PAGE_SIZE (getpagesize())
+
+static GHashTable *processes_by_cmdline;
+static GHashTable *processes_by_pid;
+
+typedef struct Map Map;
+struct Map
+{
+ char * filename;
+ gulong start;
+ gulong end;
+ gulong offset;
+#if 0
+ gboolean do_offset;
+#endif
+
+ BinFile * bin_file;
+};
+
+struct Process
+{
+ char *cmdline;
+
+ GList *maps;
+ GList *bad_pages;
+
+ int pid;
+};
+
+static void
+initialize (void)
+{
+ if (!processes_by_cmdline)
+ {
+ processes_by_cmdline = g_hash_table_new (g_str_hash, g_str_equal);
+ processes_by_pid = g_hash_table_new (g_direct_hash, g_direct_equal);
+ }
+}
+
+static GList *
+read_maps (int pid)
+{
+ char *name = g_strdup_printf ("/proc/%d/maps", pid);
+ char buffer[1024];
+ FILE *in;
+ GList *result = NULL;
+
+ in = fopen (name, "r");
+ if (!in)
+ {
+#if 0
+ g_print ("could not open %d: %s\n", pid, g_strerror (errno));
+#endif
+ g_free (name);
+ return NULL;
+ }
+
+ while (fgets (buffer, sizeof (buffer) - 1, in))
+ {
+ char file[256];
+ int count;
+ gulong start;
+ gulong end;
+ gulong offset;
+
+#if 0
+ g_print ("buffer: %s\n", buffer);
+#endif
+
+ count = sscanf (
+ buffer, "%lx-%lx %*15s %lx %*x:%*x %*u %255s",
+ &start, &end, &offset, file);
+ if (count == 4)
+ {
+ Map *map;
+
+ map = g_new (Map, 1);
+
+ map->filename = g_strdup (file);
+ map->start = start;
+ map->end = end;
+
+ map->offset = offset;
+
+ map->bin_file = NULL;
+
+ result = g_list_prepend (result, map);
+ }
+#if 0
+ else
+ {
+ g_print ("scanf\n");
+ }
+#endif
+ }
+
+ g_free (name);
+ fclose (in);
+ return result;
+}
+
+
+static Process *
+create_process (const char *cmdline, int pid)
+{
+ Process *p;
+
+ p = g_new (Process, 1);
+
+ if (*cmdline != '\0')
+ p->cmdline = g_strdup_printf ("[%s]", cmdline);
+ else
+ p->cmdline = g_strdup_printf ("[pid %d]", pid);
+
+ p->bad_pages = NULL;
+ p->maps = NULL;
+ p->pid = pid;
+
+ g_assert (!g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid)));
+ g_assert (!g_hash_table_lookup (processes_by_cmdline, cmdline));
+
+ g_hash_table_insert (processes_by_pid, GINT_TO_POINTER (pid), p);
+ g_hash_table_insert (processes_by_cmdline, g_strdup (cmdline), p);
+
+ return p;
+}
+
+static Map *
+process_locate_map (Process *process, gulong addr)
+{
+ GList *list;
+
+ for (list = process->maps; list != NULL; list = list->next)
+ {
+ Map *map = list->data;
+
+ if ((addr >= map->start) &&
+ (addr < map->end))
+ {
+ return map;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+process_free_maps (Process *process)
+{
+ GList *list;
+
+ for (list = process->maps; list != NULL; list = list->next)
+ {
+ Map *map = list->data;
+
+ if (map->filename)
+ g_free (map->filename);
+
+ if (map->bin_file)
+ bin_file_free (map->bin_file);
+
+ g_free (map);
+ }
+
+ g_list_free (process->maps);
+}
+
+static gboolean
+process_has_page (Process *process, gulong addr)
+{
+ if (process_locate_map (process, addr))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void
+process_ensure_map (Process *process, int pid, gulong addr)
+{
+ /* Round down to closest page */
+
+ addr = (addr - addr % PAGE_SIZE);
+
+ if (process_has_page (process, addr))
+ return;
+
+ if (g_list_find (process->bad_pages, (gpointer)addr))
+ return;
+
+ /* a map containing addr was not found */
+ if (process->maps)
+ process_free_maps (process);
+
+ process->maps = read_maps (pid);
+
+ if (!process_has_page (process, addr))
+ {
+#if 0
+ g_print ("Bad page: %p\n", addr);
+#endif
+ process->bad_pages = g_list_prepend (process->bad_pages, (gpointer)addr);
+ }
+}
+
+static gboolean
+do_idle_free (gpointer d)
+{
+ g_free (d);
+ return FALSE;
+}
+
+static char *
+idle_free (char *d)
+{
+ g_idle_add (do_idle_free, d);
+ return d;
+}
+
+static char *
+get_cmdline (int pid)
+{
+ char *cmdline;
+ char *filename = idle_free (g_strdup_printf ("/proc/%d/cmdline", pid));
+
+ if (g_file_get_contents (filename, &cmdline, NULL, NULL))
+ {
+ if (*cmdline == '\0')
+ {
+ g_free (cmdline);
+ return NULL;
+ }
+ return cmdline;
+ }
+
+ return NULL;
+}
+
+static char *
+get_statname (int pid)
+{
+ char *stat;
+ char *filename = idle_free (g_strdup_printf ("/proc/%d/stat", pid));
+
+#if 0
+ g_print ("stat %d\n", pid);
+#endif
+
+ if (g_file_get_contents (filename, &stat, NULL, NULL))
+ {
+ char result[200];
+
+ idle_free (stat);
+
+ if (sscanf (stat, "%*d %200s %*s", result) == 1)
+ return g_strndup (result, 200);
+ }
+#if 0
+ g_print ("return null\n");
+#endif
+
+ return NULL;
+}
+
+static char *
+get_pidname (int pid)
+{
+ if (pid == -1)
+ return g_strdup_printf ("kernel");
+ else
+ return g_strdup_printf ("pid %d", pid);
+}
+
+static char *
+get_name (int pid)
+{
+ char *cmdline = NULL;
+
+ if ((cmdline = get_cmdline (pid)))
+ return cmdline;
+
+ if ((cmdline = get_statname (pid)))
+ return cmdline;
+
+ return get_pidname (pid);
+}
+
+Process *
+process_get_from_pid (int pid)
+{
+ Process *p;
+ gchar *cmdline = NULL;
+
+ initialize();
+
+ p = g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid));
+
+ if (p)
+ return p;
+
+ cmdline = get_name (pid);
+
+ p = g_hash_table_lookup (processes_by_cmdline, cmdline);
+ if (p)
+ return p;
+ else
+ return create_process (idle_free (cmdline), pid);
+}
+
+const Symbol *
+process_lookup_symbol (Process *process, gulong address)
+{
+ static Symbol undefined;
+ const Symbol *result;
+ static Symbol kernel;
+ Map *map = process_locate_map (process, address);
+
+/* g_print ("addr: %x\n", address); */
+
+ if (address == 0x1)
+ {
+ kernel.name = "in kernel";
+ kernel.address = 0x0001337;
+ return &kernel;
+ }
+ else if (!map)
+ {
+ if (undefined.name)
+ g_free (undefined.name);
+ undefined.name = g_strdup_printf ("??? %s", process->cmdline);
+ undefined.address = 0xBABE0001;
+
+#if 0
+ g_print ("no map for %p (%s)\n", address, process->cmdline);
+#endif
+ return &undefined;
+ }
+
+#if 0
+ g_print ("has map: %s\n", process->cmdline);
+#endif
+
+#if 0
+ g_print ("has map: %s\n", process->cmdline);
+#endif
+
+/* if (map->do_offset) */
+/* address -= map->start; */
+
+#if 0
+ /* convert address to file coordinates */
+ g_print ("looking up %p ", address);
+#endif
+
+ address -= map->start;
+ address += map->offset;
+
+ if (!map->bin_file)
+ map->bin_file = bin_file_new (map->filename);
+
+/* g_print ("%s: start: %p, load: %p\n", */
+/* map->filename, map->start, bin_file_get_load_address (map->bin_file)); */
+
+ result = bin_file_lookup_symbol (map->bin_file, address);
+
+#if 0
+ g_print (" ---> %s\n", result->name);
+#endif
+
+/* g_print ("(%x) %x %x name; %s\n", address, map->start, map->offset, result->name); */
+
+ return result;
+}
+
+const char *
+process_get_cmdline (Process *process)
+{
+ return process->cmdline;
+}
+
+static void
+free_process (gpointer key, gpointer value, gpointer data)
+{
+ char *cmdline = key;
+ Process *process = value;
+
+#if 0
+ g_print ("freeing: %p\n", process);
+ memset (process, '\0', sizeof (Process));
+#endif
+ g_free (process->cmdline);
+#if 0
+ process->cmdline = "You are using free()'d memory";
+#endif
+ process_free_maps (process);
+ g_list_free (process->bad_pages);
+ g_free (cmdline);
+
+ g_free (process);
+}
+
+void
+process_flush_caches (void)
+{
+ if (!processes_by_cmdline)
+ return;
+ g_hash_table_foreach (processes_by_cmdline, free_process, NULL);
+
+ g_hash_table_destroy (processes_by_cmdline);
+ g_hash_table_destroy (processes_by_pid);
+
+ processes_by_cmdline = NULL;
+ processes_by_pid = NULL;
+}
diff --git a/process.h b/process.h
new file mode 100644
index 0000000..6ad1eba
--- /dev/null
+++ b/process.h
@@ -0,0 +1,61 @@
+/* MemProf -- memory profiler and leak detector
+ * Copyright 1999, 2000, 2001, Red Hat, Inc.
+ * Copyright 2002, Kristian Rietveld
+ *
+ * Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PROCESS_H
+#define PROCESS_H
+
+#include "binfile.h"
+
+typedef struct Process Process;
+
+/* We are making the assumption that pid's are not recycled during
+ * a profiling run. That is wrong, but necessary to avoid reading
+ * from /proc/<pid>/maps on every sample (which would be a race
+ * condition anyway).
+ *
+ * If the address passed to new_from_pid() is somewhere that hasn't
+ * been checked before, the mappings are reread for the Process. This
+ * means that if some previously sampled pages have been unmapped,
+ * they will be lost and appear as "???" on the profile.
+ *
+ * To flush the pid cache, call process_flush_caches().
+ * This will invalidate all instances of Process.
+ *
+ */
+
+void process_flush_caches (void);
+Process * process_get_from_pid (int pid);
+void process_ensure_map (Process *process,
+ int pid,
+ gulong address);
+const Symbol *process_lookup_symbol (Process *process,
+ gulong address);
+const Symbol *process_lookup_symbol_with_filename (Process *process,
+ int pid,
+ gulong map_start,
+ const char *filename,
+ gulong address);
+const char * process_get_cmdline (Process *process);
+
+
+#endif
diff --git a/profile.c b/profile.c
new file mode 100644
index 0000000..f3dd0e9
--- /dev/null
+++ b/profile.c
@@ -0,0 +1,878 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "binfile.h"
+#include "process.h"
+#include "stackstash.h"
+#include "profile.h"
+#include "sfile.h"
+
+typedef struct Node Node;
+
+static void
+update()
+{
+#if 0
+ while (g_main_pending())
+ g_main_iteration (FALSE);
+#endif
+}
+
+static guint
+direct_hash_no_null (gconstpointer v)
+{
+ g_assert (v != NULL);
+ return GPOINTER_TO_UINT (v);
+}
+
+struct Node
+{
+ ProfileObject *object;
+
+ Node *siblings; /* siblings in the call tree */
+ Node *children; /* children in the call tree */
+ Node *parent; /* parent in call tree */
+ Node *next; /* nodes that correspond to same object are linked though
+ * this pointer
+ */
+
+ guint total;
+ guint self;
+
+ gboolean toplevel;
+};
+
+struct Profile
+{
+ gint size;
+ Node * call_tree;
+
+ /* This table is really a cache. We can build it from the call_tree */
+ GHashTable * nodes_by_object;
+};
+
+static SFormat *
+create_format (void)
+{
+ SType object_type = 0;
+ SType node_type = 0;
+
+ return sformat_new (
+ sformat_new_record (
+ "profile", NULL,
+ sformat_new_integer ("size"),
+ sformat_new_pointer ("call_tree", &node_type),
+ sformat_new_list (
+ "objects", NULL,
+ sformat_new_record (
+ "object", &object_type,
+ sformat_new_string ("name"),
+ sformat_new_integer ("total"),
+ sformat_new_integer ("self"),
+ NULL)),
+ sformat_new_list (
+ "nodes", NULL,
+ sformat_new_record (
+ "node", &node_type,
+ sformat_new_pointer ("object", &object_type),
+ sformat_new_pointer ("siblings", &node_type),
+ sformat_new_pointer ("children", &node_type),
+ sformat_new_pointer ("parent", &node_type),
+ sformat_new_integer ("total"),
+ sformat_new_integer ("self"),
+ sformat_new_integer ("toplevel"),
+ NULL)),
+ NULL));
+}
+
+static void
+add_object (gpointer key, gpointer value, gpointer data)
+{
+ SFileOutput *output = data;
+ ProfileObject *object = key;
+
+ sfile_begin_add_record (output, "object");
+
+ sfile_add_string (output, "name", object->name);
+ sfile_add_integer (output, "total", object->total);
+ sfile_add_integer (output, "self", object->self);
+
+ sfile_end_add (output, "object", object);
+}
+
+static void
+serialize_call_tree (Node *node, SFileOutput *output)
+{
+ if (!node)
+ return;
+
+ sfile_begin_add_record (output, "node");
+ sfile_add_pointer (output, "object", node->object);
+ sfile_add_pointer (output, "siblings", node->siblings);
+ sfile_add_pointer (output, "children", node->children);
+ sfile_add_pointer (output, "parent", node->parent);
+ sfile_add_integer (output, "total", node->total);
+ sfile_add_integer (output, "self", node->self);
+ sfile_add_integer (output, "toplevel", node->toplevel);
+ sfile_end_add (output, "node", node);
+
+ serialize_call_tree (node->siblings, output);
+ serialize_call_tree (node->children, output);
+}
+
+gboolean
+profile_save (Profile *profile,
+ const char *file_name,
+ GError **err)
+{
+ gboolean result;
+
+ SFormat *format = create_format ();
+ SFileOutput *output = sfile_output_new (format);
+
+ sfile_begin_add_record (output, "profile");
+
+ sfile_add_integer (output, "size", profile->size);
+ sfile_add_pointer (output, "call_tree", profile->call_tree);
+
+ sfile_begin_add_list (output, "objects");
+ g_hash_table_foreach (profile->nodes_by_object, add_object, output);
+ sfile_end_add (output, "objects", NULL);
+
+ sfile_begin_add_list (output, "nodes");
+ serialize_call_tree (profile->call_tree, output);
+ sfile_end_add (output, "nodes", NULL);
+
+ sfile_end_add (output, "profile", NULL);
+
+ result = sfile_output_save (output, file_name, err);
+
+ sformat_free (format);
+ sfile_output_free (output);
+
+ return result;
+}
+
+static void
+make_hash_table (Node *node, GHashTable *table)
+{
+ if (!node)
+ return;
+
+ g_assert (node->object);
+
+ node->next = g_hash_table_lookup (table, node->object);
+ g_hash_table_insert (table, node->object, node);
+
+ g_assert (node->siblings != (void *)0x11);
+
+ make_hash_table (node->siblings, table);
+ make_hash_table (node->children, table);
+}
+
+Profile *
+profile_load (const char *filename, GError **err)
+{
+ SFormat *format;
+ SFileInput *input;
+ Profile *profile;
+ int n, i;
+
+ format = create_format ();
+ input = sfile_load (filename, format, err);
+
+ if (!input)
+ return NULL;
+
+ profile = g_new (Profile, 1);
+
+ profile->nodes_by_object =
+ g_hash_table_new (direct_hash_no_null, g_direct_equal);
+
+ sfile_begin_get_record (input, "profile");
+
+ sfile_get_integer (input, "size", &profile->size);
+ sfile_get_pointer (input, "call_tree", (void **)&profile->call_tree);
+
+ n = sfile_begin_get_list (input, "objects");
+ for (i = 0; i < n; ++i)
+ {
+ ProfileObject *obj = g_new (ProfileObject, 1);
+
+ sfile_begin_get_record (input, "object");
+
+ sfile_get_string (input, "name", &obj->name);
+ sfile_get_integer (input, "total", (gint32 *)&obj->total);
+ sfile_get_integer (input, "self", (gint32 *)&obj->self);
+
+ sfile_end_get (input, "object", obj);
+ }
+ sfile_end_get (input, "objects", NULL);
+
+ profile->call_tree = NULL;
+ n = sfile_begin_get_list (input, "nodes");
+ for (i = 0; i < n; ++i)
+ {
+ Node *node = g_new (Node, 1);
+
+ sfile_begin_get_record (input, "node");
+
+ sfile_get_pointer (input, "object", (gpointer *)&node->object);
+ sfile_get_pointer (input, "siblings", (gpointer *)&node->siblings);
+ sfile_get_pointer (input, "children", (gpointer *)&node->children);
+ sfile_get_pointer (input, "parent", (gpointer *)&node->parent);
+ sfile_get_integer (input, "total", (gint32 *)&node->total);
+ sfile_get_integer (input, "self", (gint32 *)&node->self);
+ sfile_get_integer (input, "toplevel", &node->toplevel);
+
+ sfile_end_get (input, "node", node);
+
+ g_assert (node->siblings != (void *)0x11);
+ }
+ sfile_end_get (input, "nodes", NULL);
+ sfile_end_get (input, "profile", NULL);
+
+ sformat_free (format);
+ sfile_input_free (input);
+
+ make_hash_table (profile->call_tree, profile->nodes_by_object);
+
+ return profile;
+}
+
+static ProfileObject *
+profile_object_new (void)
+{
+ ProfileObject *obj = g_new (ProfileObject, 1);
+ obj->total = 0;
+ obj->self = 0;
+
+ return obj;
+}
+
+static void
+profile_object_free (ProfileObject *obj)
+{
+ g_free (obj->name);
+ g_free (obj);
+}
+
+static char *
+generate_key (Process *process, gulong address)
+{
+ if (address)
+ {
+ const Symbol *symbol = process_lookup_symbol (process, address);
+
+ return g_strdup_printf ("%p%s", (void *)symbol->address, symbol->name);
+ }
+ else
+ {
+ return g_strdup_printf ("p:%p", process_get_cmdline (process));
+ }
+}
+
+static char *
+generate_presentation_name (Process *process, gulong address)
+{
+ /* FIXME - not10
+ * using 0 to indicate "process" is broken
+ */
+ if (address)
+ {
+ const Symbol *symbol = process_lookup_symbol (process, address);
+
+ return g_strdup_printf ("%s", symbol->name);
+ }
+ else
+ {
+ return g_strdup_printf ("%s", process_get_cmdline (process));
+ }
+}
+
+static void
+ensure_profile_object (GHashTable *profile_objects, Process *process, gulong address)
+{
+ char *key = generate_key (process, address);
+
+ if (!g_hash_table_lookup (profile_objects, key))
+ {
+ ProfileObject *object;
+
+ object = profile_object_new ();
+ object->name = generate_presentation_name (process, address);
+
+ g_hash_table_insert (profile_objects, key, object);
+ }
+ else
+ {
+ g_free (key);
+ }
+}
+
+static ProfileObject *
+lookup_profile_object (GHashTable *profile_objects, Process *process, gulong address)
+{
+ ProfileObject *object;
+ char *key = generate_key (process, address);
+ object = g_hash_table_lookup (profile_objects, key);
+ g_free (key);
+ g_assert (object);
+ return object;
+}
+
+typedef struct Info Info;
+struct Info
+{
+ Profile *profile;
+ GHashTable *profile_objects;
+};
+
+static void
+generate_object_table (Process *process, GSList *trace, gint size, gpointer data)
+{
+ Info *info = data;
+ GSList *list;
+
+ ensure_profile_object (info->profile_objects, process, 0);
+
+ for (list = trace; list != NULL; list = list->next)
+ {
+ update ();
+ ensure_profile_object (info->profile_objects, process, (gulong)list->data);
+ }
+
+ info->profile->size += size;
+}
+
+static Node *
+node_new ()
+{
+ Node *node = g_new (Node, 1);
+ node->siblings = NULL;
+ node->children = NULL;
+ node->parent = NULL;
+ node->next = NULL;
+ node->object = NULL;
+ node->self = 0;
+ node->total = 0;
+
+ return node;
+}
+
+static Node *
+node_add_trace (Profile *profile, GHashTable *profile_objects, Node *node, Process *process,
+ GSList *trace, gint size,
+ GHashTable *seen_objects)
+{
+ ProfileObject *object;
+ Node *match = NULL;
+
+ if (!trace)
+ return node;
+
+ object = lookup_profile_object (profile_objects, process, (gulong)trace->data);
+ for (match = node; match != NULL; match = match->siblings)
+ {
+ if (match->object == object)
+ break;
+ }
+
+ if (!match)
+ {
+ match = node_new ();
+ match->object = object;
+ match->siblings = node;
+ node = match;
+
+ if (g_hash_table_lookup (seen_objects, object))
+ match->toplevel = FALSE;
+ else
+ match->toplevel = TRUE;
+
+ match->next = g_hash_table_lookup (profile->nodes_by_object, object);
+ g_hash_table_insert (profile->nodes_by_object, object, match);
+ }
+
+ g_hash_table_insert (seen_objects, object, GINT_TO_POINTER (1));
+
+#if 0
+ g_print ("%s adds %d\n", match->object->name, size);
+#endif
+ match->total += size;
+ if (!trace->next)
+ match->self += size;
+
+ match->children = node_add_trace (profile, profile_objects, match->children, process, trace->next, size,
+ seen_objects);
+
+ return node;
+}
+
+#if 0
+static void
+dump_trace (GSList *trace)
+{
+ g_print ("TRACE: ");
+ while (trace)
+ {
+ g_print ("%x ", trace->data);
+ trace = trace->next;
+ }
+ g_print ("\n\n");
+}
+#endif
+
+static void
+generate_call_tree (Process *process, GSList *trace, gint size, gpointer data)
+{
+ Info *info = data;
+ Node *match = NULL;
+ ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
+ GHashTable *seen_objects;
+
+ for (match = info->profile->call_tree; match; match = match->siblings)
+ {
+ if (match->object == proc)
+ break;
+ }
+
+ if (!match)
+ {
+ match = node_new ();
+ match->object = proc;
+ match->siblings = info->profile->call_tree;
+ info->profile->call_tree = match;
+ match->toplevel = TRUE;
+ }
+
+ g_hash_table_insert (info->profile->nodes_by_object, proc, match);
+
+ match->total += size;
+ if (!trace)
+ match->self += size;
+
+ seen_objects = g_hash_table_new (direct_hash_no_null, g_direct_equal);
+
+ g_hash_table_insert (seen_objects, proc, GINT_TO_POINTER (1));
+
+ update ();
+ match->children = node_add_trace (info->profile, info->profile_objects, match->children, process,
+ trace, size, seen_objects);
+
+ g_hash_table_destroy (seen_objects);
+}
+
+static void
+link_parents (Node *node, Node *parent)
+{
+ if (!node)
+ return;
+
+ node->parent = parent;
+
+ link_parents (node->siblings, parent);
+ link_parents (node->children, node);
+}
+
+static void
+compute_object_total (gpointer key, gpointer value, gpointer data)
+{
+ Node *node;
+ ProfileObject *object = key;
+
+ for (node = value; node != NULL; node = node->next)
+ {
+ object->self += node->self;
+ if (node->toplevel)
+ object->total += node->total;
+ }
+}
+
+Profile *
+profile_new (StackStash *stash)
+{
+ Info info;
+
+ info.profile = g_new (Profile, 1);
+ info.profile->call_tree = NULL;
+ info.profile->nodes_by_object =
+ g_hash_table_new (direct_hash_no_null, g_direct_equal);
+ info.profile->size = 0;
+
+ /* profile objects */
+ info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ stack_stash_foreach (stash, generate_object_table, &info);
+ stack_stash_foreach (stash, generate_call_tree, &info);
+ link_parents (info.profile->call_tree, NULL);
+
+ g_hash_table_foreach (info.profile->nodes_by_object, compute_object_total, NULL);
+
+ g_hash_table_destroy (info.profile_objects);
+
+ return info.profile;
+}
+
+static void
+add_trace_to_tree (ProfileDescendant **tree, GList *trace, guint size)
+{
+ GList *list;
+ GPtrArray *nodes_to_unmark = g_ptr_array_new ();
+ GPtrArray *nodes_to_unmark_recursive = g_ptr_array_new ();
+ ProfileDescendant *parent = NULL;
+ int i, len;
+
+ GPtrArray *seen_objects = g_ptr_array_new ();
+
+ for (list = trace; list != NULL; list = list->next)
+ {
+ Node *node = list->data;
+ ProfileDescendant *match = NULL;
+
+ update();
+
+ for (match = *tree; match != NULL; match = match->siblings)
+ {
+ if (match->object == node->object)
+ break;
+ }
+
+ if (!match)
+ {
+ ProfileDescendant *seen_tree_node;
+
+ /* Have we seen this object further up the tree? */
+ seen_tree_node = NULL;
+ for (i = 0; i < seen_objects->len; ++i)
+ {
+ ProfileDescendant *n = seen_objects->pdata[i];
+ if (n->object == node->object)
+ seen_tree_node = n;
+ }
+
+ if (seen_tree_node)
+ {
+ ProfileDescendant *node;
+
+ g_assert (parent);
+
+ for (node = parent; node != seen_tree_node->parent; node = node->parent)
+ {
+ node->non_recursion -= size;
+ --node->marked_non_recursive;
+ }
+
+ match = seen_tree_node;
+
+ g_ptr_array_remove_range (seen_objects, 0, seen_objects->len);
+ for (node = match; node != NULL; node = node->parent)
+ g_ptr_array_add (seen_objects, node);
+ }
+ }
+
+ if (!match)
+ {
+ match = g_new (ProfileDescendant, 1);
+
+ match->object = node->object;
+ match->non_recursion = 0;
+ match->total = 0;
+ match->self = 0;
+ match->children = NULL;
+ match->marked_non_recursive = 0;
+ match->marked_total = FALSE;
+ match->parent = parent;
+
+ match->siblings = *tree;
+ *tree = match;
+ }
+
+ if (!match->marked_non_recursive)
+ {
+ g_ptr_array_add (nodes_to_unmark, match);
+ match->non_recursion += size;
+ ++match->marked_non_recursive;
+ }
+
+ if (!match->marked_total)
+ {
+ g_ptr_array_add (nodes_to_unmark_recursive, match);
+
+ match->total += size;
+ match->marked_total = TRUE;
+ }
+
+ if (!list->next)
+ match->self += size;
+
+ g_ptr_array_add (seen_objects, match);
+
+ tree = &(match->children);
+ parent = match;
+ }
+
+ g_ptr_array_free (seen_objects, TRUE);
+
+ len = nodes_to_unmark->len;
+ for (i = 0; i < len; ++i)
+ {
+ ProfileDescendant *tree_node = nodes_to_unmark->pdata[i];
+
+ tree_node->marked_non_recursive = 0;
+ }
+
+ len = nodes_to_unmark_recursive->len;
+ for (i = 0; i < len; ++i)
+ {
+ ProfileDescendant *tree_node = nodes_to_unmark_recursive->pdata[i];
+
+ tree_node->marked_total = FALSE;
+ }
+
+ g_ptr_array_free (nodes_to_unmark, TRUE);
+ g_ptr_array_free (nodes_to_unmark_recursive, TRUE);
+}
+
+static void
+node_list_leaves (Node *node, GList **leaves)
+{
+ Node *n;
+
+ if (node->self > 0)
+ *leaves = g_list_prepend (*leaves, node);
+
+ for (n = node->children; n != NULL; n = n->siblings)
+ node_list_leaves (n, leaves);
+}
+
+static void
+add_leaf_to_tree (ProfileDescendant **tree, Node *leaf, Node *top)
+{
+ GList *trace = NULL;
+ Node *node;
+
+ for (node = leaf; node != top->parent; node = node->parent)
+ trace = g_list_prepend (trace, node);
+
+ add_trace_to_tree (tree, trace, leaf->self);
+
+ g_list_free (trace);
+}
+
+ProfileDescendant *
+profile_create_descendants (Profile *profile, ProfileObject *object)
+{
+ ProfileDescendant *tree = NULL;
+ Node *node;
+
+ node = g_hash_table_lookup (profile->nodes_by_object, object);
+
+ while (node)
+ {
+ update();
+ if (node->toplevel)
+ {
+ GList *leaves = NULL;
+ GList *list;
+
+ node_list_leaves (node, &leaves);
+
+ for (list = leaves; list != NULL; list = list->next)
+ add_leaf_to_tree (&tree, list->data, node);
+
+ g_list_free (leaves);
+ }
+ node = node->next;
+ }
+
+ return tree;
+}
+
+static ProfileCaller *
+profile_caller_new (void)
+{
+ ProfileCaller *caller = g_new (ProfileCaller, 1);
+ caller->next = NULL;
+ caller->self = 0;
+ caller->total = 0;
+ return caller;
+}
+
+ProfileCaller *
+profile_list_callers (Profile *profile,
+ ProfileObject *callee)
+{
+ Node *callee_node;
+ Node *node;
+ GHashTable *callers_by_object;
+ GHashTable *seen_callers;
+ ProfileCaller *result = NULL;
+
+ callers_by_object =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ seen_callers = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ callee_node = g_hash_table_lookup (profile->nodes_by_object, callee);
+
+ for (node = callee_node; node; node = node->next)
+ {
+ ProfileObject *object;
+ if (node->parent)
+ object = node->parent->object;
+ else
+ object = NULL;
+
+ if (!g_hash_table_lookup (callers_by_object, object))
+ {
+ ProfileCaller *caller = profile_caller_new ();
+ caller->object = object;
+ g_hash_table_insert (callers_by_object, object, caller);
+
+ caller->next = result;
+ result = caller;
+ }
+ }
+
+ for (node = callee_node; node != NULL; node = node->next)
+ {
+ Node *top_caller;
+ Node *top_callee;
+ Node *n;
+ ProfileCaller *caller;
+ ProfileObject *object;
+
+ if (node->parent)
+ object = node->parent->object;
+ else
+ object = NULL;
+
+ caller = g_hash_table_lookup (callers_by_object, object);
+
+ /* find topmost node/parent pair identical to this node/parent */
+ top_caller = node->parent;
+ top_callee = node;
+ for (n = node; n && n->parent; n = n->parent)
+ {
+ if (n->object == node->object &&
+ n->parent->object == node->parent->object)
+ {
+ top_caller = n->parent;
+ top_callee = n;
+ }
+ }
+
+ if (!g_hash_table_lookup (seen_callers, top_caller))
+ {
+ caller->total += top_callee->total;
+
+ g_hash_table_insert (seen_callers, top_caller, (void *)0x1);
+ }
+
+ if (node->self > 0)
+ caller->self += node->self;
+ }
+
+ g_hash_table_destroy (seen_callers);
+ g_hash_table_destroy (callers_by_object);
+
+ return result;
+
+}
+
+static void
+node_free (Node *node)
+{
+ if (!node)
+ return;
+
+ node_free (node->siblings);
+ node_free (node->children);
+ g_free (node);
+}
+
+static void
+free_object (gpointer key, gpointer value, gpointer data)
+{
+ profile_object_free (key);
+}
+
+void
+profile_free (Profile *profile)
+{
+ g_hash_table_foreach (profile->nodes_by_object, free_object, NULL);
+
+ node_free (profile->call_tree);
+
+ g_hash_table_destroy (profile->nodes_by_object);
+
+ g_free (profile);
+}
+
+void
+profile_descendant_free (ProfileDescendant *descendant)
+{
+ if (!descendant)
+ return;
+
+ profile_descendant_free (descendant->siblings);
+ profile_descendant_free (descendant->children);
+
+ g_free (descendant);
+}
+
+void
+profile_caller_free (ProfileCaller *caller)
+{
+ if (!caller)
+ return;
+
+ profile_caller_free (caller->next);
+ g_free (caller);
+}
+
+static void
+build_object_list (gpointer key, gpointer value, gpointer data)
+{
+ ProfileObject *object = key;
+ GList **objects = data;
+
+ *objects = g_list_prepend (*objects, object);
+}
+
+GList *
+profile_get_objects (Profile *profile)
+{
+ GList *objects = NULL;
+
+ g_hash_table_foreach (profile->nodes_by_object, build_object_list, &objects);
+
+ return objects;
+}
+
+gint
+profile_get_size (Profile *profile)
+{
+ return profile->size;
+}
diff --git a/profile.h b/profile.h
new file mode 100644
index 0000000..edc1c45
--- /dev/null
+++ b/profile.h
@@ -0,0 +1,76 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include "binfile.h"
+#include "process.h"
+#include "stackstash.h"
+
+typedef struct Profile Profile;
+typedef struct ProfileObject ProfileObject;
+typedef struct ProfileDescendant ProfileDescendant;
+typedef struct ProfileCaller ProfileCaller;
+
+struct ProfileObject
+{
+ char * name; /* identifies this object uniquely */
+
+ guint total; /* sum of all toplevel totals */
+ guint self; /* sum of all selfs */
+};
+
+struct ProfileDescendant
+{
+ ProfileObject * object;
+ guint self;
+ guint total;
+ guint non_recursion;
+ ProfileDescendant * parent;
+ ProfileDescendant * siblings;
+ ProfileDescendant * children;
+
+ int marked_non_recursive;
+ int marked_total;
+};
+
+struct ProfileCaller
+{
+ ProfileObject * object; /* can be NULL */
+ guint total;
+ guint self;
+
+ ProfileCaller * next;
+};
+
+Profile * profile_new (StackStash *stash);
+void profile_free (Profile *profile);
+gint profile_get_size (Profile *profile);
+GList * profile_get_objects (Profile *profile);
+ProfileDescendant *profile_create_descendants (Profile *prf,
+ ProfileObject *object);
+ProfileCaller * profile_list_callers (Profile *profile,
+ ProfileObject *callee);
+void profile_caller_free (ProfileCaller *caller);
+void profile_descendant_free (ProfileDescendant *descendant);
+
+gboolean profile_save (Profile *profile,
+ const char *file_name,
+ GError **err);
+Profile * profile_load (const char *filename,
+ GError **err);
diff --git a/sfile.c b/sfile.c
new file mode 100644
index 0000000..31a152c
--- /dev/null
+++ b/sfile.c
@@ -0,0 +1,1980 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#if 0
+#include <bzlib.h>
+#endif
+#include "sfile.h"
+
+typedef struct State State;
+typedef struct Transition Transition;
+typedef struct Fragment Fragment;
+
+struct SFormat
+{
+ State *begin;
+ State *end;
+};
+
+enum
+{
+ TYPE_UNDEFINED = 0,
+ TYPE_POINTER,
+ TYPE_STRING,
+ TYPE_INTEGER,
+ TYPE_GENERIC_RECORD,
+ TYPE_GENERIC_LIST,
+ TYPE_VOID,
+ N_BUILTIN_TYPES,
+};
+
+typedef enum
+{
+ BEGIN,
+ VALUE,
+ END
+} TransitionKind;
+
+struct Transition
+{
+ SType type;
+ TransitionKind kind;
+ State *to;
+ char *element; /* for begin/end transitions */
+ SType target_type; /* for pointer transitions */
+};
+
+struct State
+{
+ GQueue *transitions;
+};
+
+struct Fragment
+{
+ Transition *enter, *exit;
+};
+
+static void
+set_error (GError **err, gint code, const char *format, va_list args)
+{
+ char *msg;
+
+ if (!err)
+ return;
+
+ msg = g_strdup_vprintf (format, args);
+
+ if (*err == NULL)
+ {
+ *err = g_error_new_literal (G_MARKUP_ERROR, code, msg);
+ }
+ else
+ {
+ /* Warning text from GLib */
+ g_warning ("GError set over the top of a previous GError or uninitialized memory.\n"
+ "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n"
+ "The overwriting error message was: %s",
+ msg);
+ }
+
+ g_free (msg);
+}
+
+static void
+set_unknown_element_error (GError **err, const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ set_error (err, G_MARKUP_ERROR_UNKNOWN_ELEMENT, format, args);
+ va_end (args);
+}
+
+static void
+set_unknown_attribute_error (GError **err, const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ set_error (err, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, format, args);
+ va_end (args);
+}
+
+static void
+set_invalid_content_error (GError **err, const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ set_error (err, G_MARKUP_ERROR_INVALID_CONTENT, format, args);
+ va_end (args);
+}
+
+static Transition *
+transition_new (const char *element,
+ TransitionKind kind,
+ SType type,
+ State *from,
+ State *to)
+{
+ Transition *t = g_new (Transition, 1);
+
+ g_assert (element || kind == VALUE);
+
+ t->element = element? g_strdup (element) : NULL;
+ t->kind = kind;
+ t->type = type;
+ t->to = to;
+ t->target_type = TYPE_UNDEFINED;
+
+ if (from)
+ g_queue_push_tail (from->transitions, t);
+
+ return t;
+}
+
+static void
+transition_free (Transition *transition)
+{
+ if (transition->element)
+ g_free (transition->element);
+ g_free (transition);
+}
+
+static State *
+state_new (void)
+{
+ State *state = g_new (State, 1);
+ state->transitions = g_queue_new ();
+ return state;
+}
+
+static void
+state_free (State *state)
+{
+ GList *list;
+
+ for (list = state->transitions->head; list; list = list->next)
+ {
+ Transition *transition = list->data;
+
+ transition_free (transition);
+ }
+
+ g_queue_free (state->transitions);
+ g_free (state);
+}
+
+SFormat *
+sformat_new (gpointer f)
+{
+ SFormat *sformat = g_new0 (SFormat, 1);
+ Fragment *fragment = f;
+
+ sformat->begin = state_new ();
+ sformat->end = state_new ();
+
+ g_queue_push_tail (sformat->begin->transitions, fragment->enter);
+ fragment->exit->to = sformat->end;
+
+ g_free (fragment);
+
+ return sformat;
+}
+
+#if 0
+SFormat *
+sformat_new_optional (gpointer f)
+{
+ SFormat *sformat = g_new0 (SFormat, 1);
+ Fragment *fragment = f;
+
+ sformat->begin = state_new ();
+ sformat->end = state_new ();
+}
+#endif
+
+static void
+add_state (State *state, GHashTable *seen_states, GQueue *todo_list)
+{
+ if (!g_hash_table_lookup (seen_states, state))
+ {
+ g_hash_table_insert (seen_states, state, state);
+ g_queue_push_tail (todo_list, state);
+ }
+}
+
+void
+sformat_free (SFormat *format)
+{
+ GHashTable *seen_states = g_hash_table_new (g_direct_hash, g_direct_equal);
+ GQueue *todo_list = g_queue_new ();
+
+ add_state (format->begin, seen_states, todo_list);
+ add_state (format->end, seen_states, todo_list);
+
+ while (!g_queue_is_empty (todo_list))
+ {
+ GList *list;
+ State *state = g_queue_pop_head (todo_list);
+
+ for (list = state->transitions->head; list != NULL; list = list->next)
+ {
+ Transition *transition = list->data;
+ add_state (transition->to, seen_states, todo_list);
+ }
+
+ state_free (state);
+ }
+
+ g_hash_table_destroy (seen_states);
+ g_queue_free (todo_list);
+}
+
+static GQueue *
+fragment_queue (Fragment *fragment1, va_list args)
+{
+ GQueue *fragments = g_queue_new ();
+ Fragment *fragment;
+
+ g_queue_push_tail (fragments, fragment1);
+
+ fragment = va_arg (args, Fragment *);
+ while (fragment)
+ {
+ g_queue_push_tail (fragments, fragment);
+ fragment = va_arg (args, Fragment *);
+ }
+
+ return fragments;
+}
+
+#if 0
+/* Consider adding unions at some point
+ *
+ * To be useful they should probably be anonymous, so that
+ * the union itself doesn't have a representation in the
+ * xml file.
+ *
+ * API:
+ * sformat_new_union (gpointer content1, ...);
+ *
+ * char *content = begin_get_union ();
+ * if (strcmp (content, ...) == 0)
+ * get_pointer ();
+ * else if (strcmp (content, ...) == 0)
+ *
+ * ;
+ *
+ * Annoying though, that we then won't have the nice one-to-one
+ * correspondence between begin()/end() calls and <element></element>s
+ * Actually, we will probably have to have <union>asdlfkj</union>
+ * elements. That will make things a lot easier, and unions are
+ * still pretty useful if you put big things like lists in them.
+ *
+ * We may also consider adding anonymous records. These will
+ * not be able to have pointers associated with them though
+ * (because there wouldn't be a natural place
+ *
+ *
+ * Also consider adding the following data types:
+ *
+ * Binary blobs of data, stored as base64 perhaps
+ * floating point values. How do we store those portably
+ * without losing precision? Gnumeric may know.
+ * enums, stored as strings
+ * booleans
+ */
+gpointer
+sformat_new_union (const char *name,
+ gpointer content1,
+ ...)
+{
+ va_list args;
+ GQueue *fragments;
+ GList *list;
+ Fragment *fragment;
+ Transition *enter, *exit;
+ State *begin;
+ State *end;
+
+ va_start (args, content1);
+
+ fragments = fragment_queue (args);
+
+ va_end (args);
+
+ begin = state_new ();
+ end = state_new ();
+
+ enter = transition_new (name, TRANSITION_BEGIN_UNION, NULL, begin);
+ exit = transition_new (name, TRANSITION_END_UNION, end, NULL);
+
+ for (list = fragments->head; list; list = list->next)
+ {
+ Fragment *fragment = list->data;
+
+ g_queue_push_tail (begin->transitions, fragment->enter);
+ }
+
+ for (list = fragments->head; list; list = list->next)
+ {
+ fragment = list->data;
+
+ fragment->exit->to = end;
+
+ g_free (fragment);
+ }
+
+ g_queue_free (fragments);
+
+ fragment = g_new (Fragment, 1);
+ fragment->enter = enter;
+ fragment->exit = exit;
+
+ return fragment;
+}
+#endif
+
+#define RECORD_SHIFT (sizeof (SType) * 8 - 1)
+#define LIST_SHIFT (sizeof (SType) * 8 - 2)
+
+static SType
+define_type (SType *type, SType fallback)
+{
+ static SType type_ids = N_BUILTIN_TYPES;
+
+ if (type)
+ {
+ if (*type == 0)
+ *type = type_ids++;
+
+ return *type;
+ }
+
+ return fallback;
+}
+
+static gboolean
+is_record_type (SType type)
+{
+ /* FIMXE - not10 */
+ return TRUE;
+}
+
+static gboolean
+is_list_type (SType type)
+{
+ /* FIXME - not10 */
+ return TRUE;
+}
+
+gpointer
+sformat_new_record (const char * name,
+ SType *type,
+ gpointer content1,
+ ...)
+{
+ va_list args;
+ GQueue *fragments;
+ State *begin, *state;
+ Fragment *fragment;
+ GList *list;
+ SType real_type;
+
+ /* Build queue of fragments */
+ va_start (args, content1);
+
+ fragments = fragment_queue (content1, args);
+
+ va_end (args);
+
+ /* chain fragments together */
+ state = begin = state_new ();
+
+ for (list = fragments->head; list != NULL; list = list->next)
+ {
+ fragment = list->data;
+
+ g_queue_push_tail (state->transitions, fragment->enter);
+
+ state = state_new ();
+ fragment->exit->to = state;
+ }
+
+ real_type = define_type (type, TYPE_GENERIC_RECORD);
+
+ /* Return resulting fragment */
+ fragment = g_new (Fragment, 1);
+ fragment->enter = transition_new (name, BEGIN, real_type, NULL, begin);
+ fragment->exit = transition_new (name, END, real_type, state, NULL);
+
+ return fragment;
+}
+
+gpointer
+sformat_new_list (const char *name,
+ SType *type,
+ gpointer content)
+{
+ Fragment *m = content;
+ State *list_state;
+ Transition *enter, *exit;
+ SType real_type;
+
+ list_state = state_new ();
+
+ real_type = define_type (type, TYPE_GENERIC_LIST);
+
+ enter = transition_new (name, BEGIN, real_type, NULL, list_state);
+ exit = transition_new (name, END, real_type, list_state, NULL);
+
+ g_queue_push_tail (list_state->transitions, m->enter);
+ m->exit->to = list_state;
+
+ m->enter = enter;
+ m->exit = exit;
+
+ return m;
+}
+
+static gpointer
+sformat_new_value (const char *name,
+ SType type)
+{
+ Fragment *m = g_new (Fragment, 1);
+ State *before, *after;
+ Transition *value;
+
+ before = state_new ();
+ after = state_new ();
+
+ m->enter = transition_new (name, BEGIN, type, NULL, before);
+ m->exit = transition_new (name, END, type, after, NULL);
+ value = transition_new (NULL, VALUE, type, before, after);
+
+ return m;
+}
+
+gpointer
+sformat_new_pointer (const char *name,
+ SType *target_type)
+{
+ Fragment *fragment = sformat_new_value (name, TYPE_POINTER);
+ Transition *value;
+
+ /* store the target type in the value transition */
+ value = fragment->enter->to->transitions->head->data;
+ value->target_type = define_type (target_type, TYPE_VOID);
+
+ return fragment;
+}
+
+gpointer
+sformat_new_integer (const char *name)
+{
+ return sformat_new_value (name, TYPE_INTEGER);
+}
+
+gpointer
+sformat_new_string (const char *name)
+{
+ return sformat_new_value (name, TYPE_STRING);
+}
+
+static const State *
+sformat_get_start_state (SFormat *format)
+{
+ return format->begin;
+}
+
+static gboolean
+sformat_is_end_state (SFormat *format, const State *state)
+{
+ return format->end == state;
+}
+
+static const State *
+state_transition_check (const State *state,
+ const char *element,
+ TransitionKind kind,
+ SType *type)
+{
+ GList *list;
+
+ for (list = state->transitions->head; list; list = list->next)
+ {
+ Transition *transition = list->data;
+
+ if (transition->kind == kind &&
+ strcmp (element, transition->element) == 0)
+ {
+ *type = transition->type;
+ return transition->to;
+ }
+ }
+
+ return NULL;
+}
+
+static const State *
+state_transition_begin (const State *state, const char *element, SType *type)
+{
+ return state_transition_check (state, element, BEGIN, type);
+}
+
+static const State *
+state_transition_end (const State *state, const char *element, SType *type)
+{
+ return state_transition_check (state, element, END, type);
+}
+
+static const State *
+state_transition_text (const State *state, SType *type, SType *target_type)
+{
+ GList *list;
+
+ for (list = state->transitions->head; list; list = list->next)
+ {
+ Transition *transition = list->data;
+
+ if (transition->kind == VALUE)
+ {
+ *type = transition->type;
+
+ if (*type == TYPE_POINTER && target_type)
+ *target_type = transition->target_type;
+
+ /* There will never be more than one allowed value transition for
+ * a given state
+ */
+ return transition->to;
+ }
+#if 0
+ else
+ g_print ("transition: %d (%s)\n", transition->kind, transition->element);
+#endif
+ }
+
+ return NULL;
+}
+
+/* reading */
+typedef struct BuildContext BuildContext;
+typedef struct Instruction Instruction;
+
+struct Instruction
+{
+ TransitionKind kind;
+ SType type;
+
+ char *name;
+ union
+ {
+ struct
+ {
+ gboolean is_list;
+ gboolean is_record;
+ int n_elements;
+ int id;
+ Instruction *end_instruction;
+ } begin;
+
+ struct
+ {
+ Instruction *begin_instruction;
+ gpointer object;
+ } end;
+
+ struct
+ {
+ SType target_type;
+ int target_id;
+ Instruction *target_instruction;
+ gpointer target_object;
+ gpointer *location;
+ } pointer;
+
+ struct
+ {
+ int value;
+ } integer;
+
+ struct
+ {
+ char *value;
+ } string;
+ } u;
+};
+
+struct BuildContext
+{
+ const State *state;
+
+ GArray *instructions;
+};
+
+static gboolean
+get_number (const char *text, int *number)
+{
+ char *end;
+ int result;
+ char *stripped;
+ gboolean retval;
+
+ stripped = g_strstrip (g_strdup (text));
+ result = strtol (stripped, &end, 10);
+
+ retval = (*end == '\0');
+
+ if (retval && number)
+ *number = result;
+
+ g_free (stripped);
+
+ return retval;
+}
+
+struct SFileInput
+{
+ int n_instructions;
+ Instruction *instructions;
+ Instruction *current_instruction;
+ GHashTable *instructions_by_location;
+};
+
+void
+sfile_begin_get_record (SFileInput *file, const char *name)
+{
+ Instruction *instruction = file->current_instruction++;
+
+ g_return_if_fail (instruction->kind == BEGIN);
+ g_return_if_fail (strcmp (instruction->name, name) == 0);
+ g_return_if_fail (is_record_type (instruction->type));
+}
+
+int
+sfile_begin_get_list (SFileInput *file,
+ const char *name)
+{
+ Instruction *instruction = file->current_instruction++;
+
+ g_return_val_if_fail (instruction->kind == BEGIN, 0);
+ g_return_val_if_fail (strcmp (instruction->name, name) == 0, 0);
+ g_return_val_if_fail (is_list_type (instruction->type), 0);
+
+ return instruction->u.begin.n_elements;
+}
+
+void
+sfile_get_pointer (SFileInput *file,
+ const char *name,
+ gpointer *location)
+{
+ Instruction *instruction;
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_POINTER &&
+ strcmp (instruction->name, name) == 0);
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_POINTER);
+
+ instruction->u.pointer.location = location;
+
+ *location = (gpointer) 0xFedeAbe;
+
+ if (location)
+ {
+ if (g_hash_table_lookup (file->instructions_by_location, location))
+ g_warning ("Reading into the same location twice\n");
+
+ g_hash_table_insert (file->instructions_by_location, location, instruction);
+ }
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_POINTER &&
+ strcmp (instruction->name, name) == 0);
+
+}
+
+void
+sfile_get_integer (SFileInput *file,
+ const char *name,
+ gint32 *integer)
+{
+ Instruction *instruction;
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_INTEGER &&
+ strcmp (instruction->name, name) == 0);
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_INTEGER);
+
+ if (integer)
+ *integer = instruction->u.integer.value;
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_INTEGER &&
+ strcmp (instruction->name, name) == 0);
+}
+
+void
+sfile_get_string (SFileInput *file,
+ const char *name,
+ char **string)
+{
+ Instruction *instruction;
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_STRING &&
+ strcmp (instruction->name, name) == 0);
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_STRING);
+
+ if (string)
+ *string = g_strdup (instruction->u.string.value);
+
+ instruction = file->current_instruction++;
+ g_return_if_fail (instruction->type == TYPE_STRING &&
+ strcmp (instruction->name, name) == 0);
+}
+
+static void
+hook_up_pointers (SFileInput *file)
+{
+ int i;
+
+#if 0
+ g_print ("emfle\n");
+#endif
+ for (i = 0; i < file->n_instructions; ++i)
+ {
+ Instruction *instruction = &(file->instructions[i]);
+
+ if (instruction->kind == VALUE &&
+ instruction->type == TYPE_POINTER)
+ {
+ gpointer target_object;
+ Instruction *target_instruction;
+
+ target_instruction = instruction->u.pointer.target_instruction;
+
+ if (target_instruction)
+ target_object = target_instruction->u.begin.end_instruction->u.end.object;
+ else
+ target_object = NULL;
+
+#if 0
+ g_print ("target object: %p\n", target_object);
+#endif
+
+ *(instruction->u.pointer.location) = target_object;
+ }
+ }
+}
+
+void
+sfile_end_get (SFileInput *file,
+ const char *name,
+ gpointer object)
+{
+ Instruction *instruction = file->current_instruction++;
+
+ g_return_if_fail (instruction->kind == END);
+ g_return_if_fail (strcmp (instruction->name, name) == 0);
+
+ instruction->u.end.object = object;
+
+ if (file->current_instruction == file->instructions + file->n_instructions)
+ hook_up_pointers (file);
+}
+
+static int
+get_id (const char **names, const char **values, GError **err)
+{
+ const char *id_string = NULL;
+ int id, i;
+
+ for (i = 0; names[i] != NULL; ++i)
+ {
+ if (strcmp (names[i], "id") != 0)
+ {
+ set_unknown_attribute_error (err, "Unknown attribute: %s", names[i]);
+ return -1;
+ }
+
+ if (id_string)
+ {
+ set_invalid_content_error (err, "Attribute 'id' defined twice");
+ return -1;
+ }
+
+ id_string = values[i];
+ }
+
+ if (!id_string)
+ return 0;
+
+ if (!get_number (id_string, &id) || id < 1)
+ {
+ set_invalid_content_error (err, "Bad attribute value for attribute 'id' (must be >= 1)\n");
+ return -1;
+ }
+
+ return id;
+}
+
+static void
+handle_begin_element (GMarkupParseContext *parse_context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **err)
+{
+ BuildContext *build = user_data;
+ Instruction instruction;
+
+ instruction.u.begin.id = get_id (attribute_names, attribute_values, err);
+
+ if (instruction.u.begin.id == -1)
+ return;
+
+ build->state = state_transition_begin (build->state, element_name, &instruction.type);
+ if (!build->state)
+ {
+ set_unknown_element_error (err, "<%s> unexpected here", element_name);
+ return;
+ }
+
+ /* FIXME - not10: is there really a reason to add begin/end instructions for values? */
+ instruction.name = g_strdup (element_name);
+ instruction.kind = BEGIN;
+ g_array_append_val (build->instructions, instruction);
+}
+
+static void
+handle_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **err)
+{
+ BuildContext *build = user_data;
+ Instruction instruction;
+
+ build->state = state_transition_end (build->state, element_name, &instruction.type);
+ if (!build->state)
+ {
+ set_unknown_element_error (err, "</%s> unexpected here", element_name);
+ return;
+ }
+
+ instruction.name = g_strdup (element_name);
+ instruction.kind = END;
+
+ g_array_append_val (build->instructions, instruction);
+}
+
+static gboolean
+decode_text (const char *text, char **decoded)
+{
+ int length = strlen (text);
+
+ if (length < 2)
+ return FALSE;
+
+ if (text[0] != '\"' || text[length - 1] != '\"')
+ return FALSE;
+
+ if (decoded)
+ *decoded = g_strndup (text + 1, length - 2);
+
+ return TRUE;
+}
+
+static void
+handle_text (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **err)
+{
+ BuildContext *build = user_data;
+ Instruction instruction;
+ char *free_me;
+ SType target_type;
+
+ text = free_me = g_strstrip (g_strdup (text));
+
+ if (strlen (text) == 0)
+ goto out;
+
+ build->state = state_transition_text (build->state, &instruction.type, &target_type);
+ if (!build->state)
+ {
+ int line, ch;
+ g_markup_parse_context_get_position (context, &line, &ch);
+#if 0
+ g_print ("line: %d char: %d\n", line, ch);
+#endif
+ set_invalid_content_error (err, "Unexpected text data");
+ goto out;
+ }
+
+ instruction.name = NULL;
+ instruction.kind = VALUE;
+
+ switch (instruction.type)
+ {
+ case TYPE_POINTER:
+ instruction.u.pointer.target_type = target_type;
+ if (!get_number (text, &instruction.u.pointer.target_id))
+ {
+ set_invalid_content_error (err, "Contents '%s' of pointer element is not a number", text);
+ goto out;
+ }
+ break;
+
+ case TYPE_INTEGER:
+ if (!get_number (text, &instruction.u.integer.value))
+ {
+ set_invalid_content_error (err, "Contents '%s' of integer element not a number", text);
+ goto out;
+ }
+ break;
+
+ case TYPE_STRING:
+ if (!decode_text (text, &instruction.u.string.value))
+ {
+ set_invalid_content_error (err, "Contents '%s' of text element is illformed", text);
+ goto out;
+ }
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ g_array_append_val (build->instructions, instruction);
+
+ out:
+ g_free (free_me);
+}
+
+static void
+free_instructions (Instruction *instructions, int n_instructions)
+{
+ int i;
+
+ for (i = 0; i < n_instructions; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ if (instruction->name)
+ g_free (instruction->name);
+
+ if (instruction->kind == VALUE && instruction->type == TYPE_STRING)
+ g_free (instruction->u.string.value);
+ }
+
+ g_free (instructions);
+}
+
+/* This functions makes end instructions point to the corresponding
+ * begin instructions, and counts the number of instructions
+ * contained in a begin/end pair
+ */
+static Instruction *
+process_instruction_pairs (Instruction *first)
+{
+ Instruction *instruction;
+ int n_elements;
+
+ g_assert (first->kind == BEGIN);
+
+ instruction = first + 1;
+
+ n_elements = 0;
+ while (instruction->kind != END)
+ {
+ if (instruction->kind == BEGIN)
+ {
+ instruction = process_instruction_pairs (instruction);
+ if (!instruction)
+ return NULL;
+ }
+ else
+ {
+ instruction++;
+ }
+
+ n_elements++;
+ }
+
+ first->u.begin.n_elements = n_elements;
+ first->u.begin.end_instruction = instruction;
+
+ instruction->u.end.begin_instruction = first;
+
+ return instruction + 1;
+}
+
+static gboolean
+post_process_read_instructions (Instruction *instructions, int n_instructions, GError **err)
+{
+ gboolean retval = TRUE;
+ GHashTable *instructions_by_id;
+ int i;
+
+ /* count list instructions, check pointers */
+ process_instruction_pairs (instructions);
+
+ /* Build id->instruction map */
+ instructions_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
+ for (i = 0; i < n_instructions; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ if (instruction->kind == BEGIN)
+ {
+ int id = instruction->u.begin.id;
+
+ if (id)
+ g_hash_table_insert (instructions_by_id, GINT_TO_POINTER (id), instruction);
+ }
+ }
+
+ /* Make pointer instructions point to the corresponding element */
+ for (i = 0; i < n_instructions; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ if (instruction->kind == VALUE &&
+ instruction->type == TYPE_POINTER)
+ {
+ int target_id = instruction->u.pointer.target_id;
+
+ if (target_id)
+ {
+ Instruction *target = g_hash_table_lookup (instructions_by_id,
+ GINT_TO_POINTER (target_id));
+
+ if (target)
+ {
+ if (instruction->u.pointer.target_type == target->type)
+ {
+ instruction->u.pointer.target_instruction = target;
+ }
+ else
+ {
+ set_invalid_content_error (err, "Id %d references an element of the wrong type",
+ instruction->u.pointer.target_id);
+ retval = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ set_invalid_content_error (err, "Id %d doesn't reference any record or list",
+ instruction->u.pointer.target_id);
+ retval = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ instruction->u.pointer.target_instruction = NULL;
+ }
+ }
+ }
+
+ g_hash_table_destroy (instructions_by_id);
+
+ return retval;
+}
+
+static Instruction *
+build_instructions (const char *contents, SFormat *format, int *n_instructions, GError **err)
+{
+ BuildContext build;
+ GMarkupParseContext *parse_context;
+
+ GMarkupParser parser = {
+ handle_begin_element,
+ handle_end_element,
+ handle_text,
+ NULL, /* passthrough */
+ NULL, /* error */
+ };
+
+ build.state = sformat_get_start_state (format);
+ build.instructions = g_array_new (TRUE, TRUE, sizeof (Instruction));
+
+ parse_context = g_markup_parse_context_new (&parser, 0, &build, NULL);
+
+ if (!g_markup_parse_context_parse (parse_context, contents, -1, err))
+ {
+ free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
+ return NULL;
+ }
+
+ if (!sformat_is_end_state (format, build.state))
+ {
+ set_invalid_content_error (err, "Premature end of file\n");
+
+ free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
+ return NULL;
+ }
+
+ if (!post_process_read_instructions ((Instruction *)build.instructions->data,
+ build.instructions->len, err))
+ {
+ free_instructions ((Instruction *)build.instructions->data, build.instructions->len);
+ return NULL;
+ }
+
+ *n_instructions = build.instructions->len;
+ return (Instruction *)g_array_free (build.instructions, FALSE);
+}
+
+SFileInput *
+sfile_load (const char *filename,
+ SFormat *format,
+ GError **err)
+{
+ gchar *contents;
+ gsize length;
+ SFileInput *input;
+
+ if (!g_file_get_contents (filename, &contents, &length, err))
+ return NULL;
+
+ input = g_new (SFileInput, 1);
+
+ input->instructions = build_instructions (contents, format, &input->n_instructions, err);
+
+ if (!input->instructions)
+ {
+ g_free (input);
+ g_free (contents);
+ return NULL;
+ }
+
+ g_free (contents);
+
+ input->current_instruction = input->instructions;
+ input->instructions_by_location = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ return input;
+}
+
+/* Writing */
+struct SFileOutput
+{
+ SFormat *format;
+ GArray *instructions;
+ GHashTable *objects;
+ const State *state;
+};
+
+SFileOutput *
+sfile_output_new (SFormat *format)
+{
+ SFileOutput *output = g_new (SFileOutput, 1);
+
+ output->format = format;
+ output->instructions = g_array_new (TRUE, TRUE, sizeof (Instruction));
+ output->state = sformat_get_start_state (format);
+ output->objects = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ return output;
+}
+
+void
+sfile_begin_add_record (SFileOutput *file,
+ const char *name)
+{
+ Instruction instruction;
+
+ file->state = state_transition_begin (file->state, name, &instruction.type);
+
+ g_return_if_fail (file->state);
+ g_return_if_fail (is_record_type (instruction.type));
+
+ instruction.kind = BEGIN;
+ instruction.name = g_strdup (name);
+
+ g_array_append_val (file->instructions, instruction);
+}
+
+void
+sfile_begin_add_list (SFileOutput *file,
+ const char *name)
+{
+ Instruction instruction;
+
+ file->state = state_transition_begin (file->state, name, &instruction.type);
+
+ g_return_if_fail (file->state);
+ g_return_if_fail (is_list_type (instruction.type));
+
+ instruction.kind = BEGIN;
+ instruction.name = g_strdup (name);
+
+ g_array_append_val (file->instructions, instruction);
+}
+
+void
+sfile_end_add (SFileOutput *file,
+ const char *name,
+ gpointer object)
+{
+ Instruction instruction;
+
+ if (object && g_hash_table_lookup (file->objects, object))
+ {
+ g_warning ("Adding the same object (%p) twice", object);
+ return;
+ }
+
+ file->state = state_transition_end (file->state, name, &instruction.type);
+
+ if (!file->state)
+ {
+ g_warning ("invalid call of sfile_end_add()");
+ return;
+ }
+
+ instruction.kind = END;
+ instruction.name = g_strdup (name);
+ instruction.u.end.object = object;
+
+ g_array_append_val (file->instructions, instruction);
+
+ if (object)
+ g_hash_table_insert (file->objects, object, object);
+}
+
+static void
+sfile_check_value (SFileOutput *file,
+ const char *name,
+ SType type)
+{
+ SType tmp_type;
+
+ file->state = state_transition_begin (file->state, name, &tmp_type);
+ g_return_if_fail (file->state && tmp_type == type);
+
+ file->state = state_transition_text (file->state, &type, NULL);
+ g_return_if_fail (file->state && tmp_type == type);
+
+ file->state = state_transition_end (file->state, name, &type);
+ g_return_if_fail (file->state && tmp_type == type);
+}
+
+void
+sfile_add_string (SFileOutput *file,
+ const char *name,
+ const char *string)
+{
+ Instruction instruction;
+
+ g_return_if_fail (g_utf8_validate (string, -1, NULL));
+
+ sfile_check_value (file, name, TYPE_STRING);
+
+ instruction.kind = VALUE;
+ instruction.type = TYPE_STRING;
+ instruction.name = g_strdup (name);
+ instruction.u.string.value = g_strdup (string);
+
+ g_array_append_val (file->instructions, instruction);
+}
+
+void
+sfile_add_integer (SFileOutput *file,
+ const char *name,
+ int integer)
+{
+ Instruction instruction;
+
+ sfile_check_value (file, name, TYPE_INTEGER);
+
+ instruction.kind = VALUE;
+ instruction.type = TYPE_INTEGER;
+ instruction.name = g_strdup (name);
+ instruction.u.integer.value = integer;
+
+ g_array_append_val (file->instructions, instruction);
+}
+
+void
+sfile_add_pointer (SFileOutput *file,
+ const char *name,
+ gpointer pointer)
+{
+ Instruction instruction;
+
+ sfile_check_value (file, name, TYPE_POINTER);
+
+ instruction.kind = VALUE;
+ instruction.type = TYPE_POINTER;
+ instruction.name = g_strdup (name);
+ instruction.u.pointer.target_object = pointer;
+
+ g_array_append_val (file->instructions, instruction);
+}
+
+static void
+post_process_write_instructions (SFileOutput *sfile)
+{
+ int i;
+ Instruction *instructions = (Instruction *)sfile->instructions->data;
+ int n_instructions = sfile->instructions->len;
+ int id;
+ GHashTable *instructions_by_object;
+
+ process_instruction_pairs (instructions);
+
+ /* Set all id's to -1 and create map from objects to instructions */
+
+ instructions_by_object = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (i = 0; i < n_instructions; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ if (instruction->kind == BEGIN)
+ {
+ instruction->u.begin.id = -1;
+ }
+ else if (instruction->kind == END && instruction->u.end.object)
+ {
+ g_hash_table_insert (instructions_by_object,
+ instruction->u.end.object, instruction);
+ }
+ }
+
+ /* Assign an id to all pointed-to instructions */
+ id = 1;
+ for (i = 0; i < n_instructions; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ if (instruction->type == TYPE_POINTER)
+ {
+ if (instruction->u.pointer.target_object)
+ {
+ Instruction *target;
+
+ target =
+ g_hash_table_lookup (instructions_by_object,
+ instruction->u.pointer.target_object);
+
+ if (!target)
+ {
+ g_warning ("pointer has unknown target\n");
+ return;
+ }
+
+ g_assert (target->kind == END);
+
+ if (target->u.end.begin_instruction->u.begin.id == -1)
+ target->u.end.begin_instruction->u.begin.id = id++;
+
+ instruction->u.pointer.target_id =
+ target->u.end.begin_instruction->u.begin.id;
+ }
+ else
+ {
+ instruction->u.pointer.target_id = 0;
+ }
+ }
+ }
+
+}
+
+static void
+add_indent (GString *output, int indent)
+{
+ int i;
+
+ for (i = 0; i < indent; ++i)
+ g_string_append_c (output, ' ');
+}
+
+static void
+add_integer (GString *output, int value)
+{
+ g_string_append_printf (output, "%d", value);
+}
+
+static void
+add_string (GString *output, const char *str)
+{
+ char *escaped = g_markup_escape_text (str, -1);
+ g_string_append_c (output, '\"');
+ g_string_append (output, escaped);
+ g_string_append_c (output, '\"');
+ g_free (escaped);
+}
+
+static void
+add_begin_tag (GString *output, int indent, const char *name, int id)
+{
+ add_indent (output, indent);
+
+ if (id != -1)
+ g_string_append_printf (output, "<%s id=\"%d\">", name, id);
+ else
+ g_string_append_printf (output, "<%s>", name);
+}
+
+static void
+add_end_tag (GString *output, int indent, const char *name)
+{
+ add_indent (output, indent);
+ g_string_append_printf (output, "</%s>", name);
+}
+
+static void
+add_nl (GString *output)
+{
+ g_string_append_c (output, '\n');
+}
+
+static gboolean
+file_replace (const gchar *filename,
+ const gchar *contents,
+ gssize length,
+ GError **error);
+
+#if 0
+static void
+disaster (int status)
+{
+ const char *error;
+ switch (status)
+ {
+ case BZ_PARAM_ERROR:
+ error = "BZ_PARAM_ERROR";
+ break;
+
+ case BZ_MEM_ERROR:
+ error = "BZ_MEM_ERROR";
+ break;
+
+ case BZ_OUTBUFF_FULL:
+ error = "BZ_OUTBUFF_FULL";
+ break;
+
+ default:
+ error = "Unknown error";
+ break;
+ }
+
+ g_error ("Failed to compress file: %s\n", error);
+}
+
+static void
+bz2_compress (const guchar *input, int input_length,
+ guchar **output, int *output_length)
+{
+ size_t compressed_size;
+ guchar *compressed_data;
+ int status;
+
+ g_return_if_fail (input != NULL);
+
+ /* The bzip2 manual says:
+ *
+ * To guarantee that the compressed data will fit in its buffer,
+ * allocate an output buffer of size 1% larger than the uncompressed
+ * data, plus six hundred extra bytes.
+ */
+ compressed_size = (size_t)(1.02 * input_length + 600);
+ compressed_data = g_malloc (compressed_size);
+
+ status = BZ2_bzBuffToBuffCompress (compressed_data, &compressed_size,
+ (guchar *)input, input_length,
+ 9 /* block size */,
+ 0 /* verbosity */,
+ 0 /* workfactor */);
+
+ if (status != BZ_OK)
+ disaster (status);
+
+ if (output)
+ *output = compressed_data;
+ else
+ g_free (compressed_data);
+
+ if (output_length)
+ *output_length = compressed_size;
+}
+#endif
+
+gboolean
+sfile_output_save (SFileOutput *sfile,
+ const char *filename,
+ GError **err)
+{
+ int i;
+ Instruction *instructions;
+ GString *output;
+ int indent;
+ gboolean retval;
+#if 0
+ guchar *compressed;
+ size_t compressed_size;
+#endif
+
+ g_return_val_if_fail (sfile != NULL, FALSE);
+
+ instructions = (Instruction *)sfile->instructions->data;
+
+ post_process_write_instructions (sfile);
+
+ indent = 0;
+ output = g_string_new ("");
+ for (i = 0; i < sfile->instructions->len; ++i)
+ {
+ Instruction *instruction = &(instructions[i]);
+
+ switch (instruction->kind)
+ {
+ case BEGIN:
+ add_begin_tag (output, indent, instruction->name,
+ instruction->u.begin.id);
+ add_nl (output);
+ indent += 4;
+ break;
+
+ case END:
+ indent -= 4;
+ add_end_tag (output, indent, instruction->name);
+ add_nl (output);
+ break;
+
+ case VALUE:
+ add_begin_tag (output, indent, instruction->name, -1);
+ switch (instruction->type)
+ {
+ case TYPE_INTEGER:
+ add_integer (output, instruction->u.integer.value);
+ break;
+
+ case TYPE_POINTER:
+ add_integer (output, instruction->u.pointer.target_id);
+ break;
+
+ case TYPE_STRING:
+ add_string (output, instruction->u.string.value);
+ break;
+ }
+ add_end_tag (output, 0, instruction->name);
+ add_nl (output);
+ break;
+ }
+ }
+
+#if 0
+ /* FIXME - not10: bz2 compressing the output is probably
+ * interesting at some point. For now just make sure
+ * it works without actually using it.
+ */
+ bz2_compress (output->str, output->len,
+ &compressed, &compressed_size);
+
+ g_free (compressed);
+#endif
+
+ retval = file_replace (filename, output->str, - 1, err);
+
+ g_string_free (output, TRUE);
+
+ return retval;
+}
+
+
+void
+sfile_input_free (SFileInput *file)
+{
+ free_instructions (file->instructions, file->n_instructions);
+
+ g_hash_table_destroy (file->instructions_by_location);
+
+ g_free (file);
+}
+
+void
+sfile_output_free (SFileOutput *sfile)
+{
+ Instruction *instructions;
+ int n_instructions;
+
+ n_instructions = sfile->instructions->len;
+ instructions = (Instruction *)g_array_free (sfile->instructions, FALSE);
+
+ free_instructions (instructions, n_instructions);
+
+ g_hash_table_destroy (sfile->objects);
+ g_free (sfile);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* A copy of g_file_replace() because I don't want to depend on
+ * GLib HEAD
+ */
+#include <errno.h>
+#include <sys/wait.h>
+#include <glib/gstdio.h>
+#include <unistd.h>
+
+static gboolean
+rename_file (const char *old_name,
+ const char *new_name,
+ GError **err)
+{
+ errno = 0;
+ if (g_rename (old_name, new_name) == -1)
+ {
+ int save_errno = errno;
+ gchar *display_old_name = g_filename_display_name (old_name);
+ gchar *display_new_name = g_filename_display_name (new_name);
+
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (save_errno),
+ "Failed to rename file '%s' to '%s': g_rename() failed: %s",
+ display_old_name,
+ display_new_name,
+ g_strerror (save_errno));
+
+ g_free (display_old_name);
+ g_free (display_new_name);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+set_umask_permissions (int fd,
+ GError **err)
+{
+#ifdef G_OS_WIN32
+
+ return TRUE;
+
+#else
+
+ /* All of this function is just to work around the fact that
+ * there is no way to get the umask without changing it.
+ *
+ * We can't just change-and-reset the umask because that would
+ * lead to a race condition if another thread tried to change
+ * the umask in between the getting and the setting of the umask.
+ * So we have to do the whole thing in a child process.
+ */
+
+ pid_t pid = fork ();
+
+ if (pid == -1)
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Could not change file mode: fork() failed: %s",
+ g_strerror (errno));
+
+ return FALSE;
+ }
+ else if (pid == 0)
+ {
+ /* child */
+ mode_t mask = umask (0666);
+
+ errno = 0;
+ if (fchmod (fd, 0666 & ~mask) == -1)
+ _exit (errno);
+ else
+ _exit (0);
+
+ return TRUE; /* To quiet gcc */
+ }
+ else
+ {
+ /* parent */
+ int status;
+
+ waitpid (pid, &status, 0);
+
+ if (WIFEXITED (status))
+ {
+ int chmod_errno = WEXITSTATUS (status);
+
+ if (chmod_errno == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (chmod_errno),
+ "Could not change file mode: chmod() failed: %s",
+ g_strerror (chmod_errno));
+
+ return FALSE;
+ }
+ }
+ else if (WIFSIGNALED (status))
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ G_FILE_ERROR_FAILED,
+ "Could not change file mode: Child terminated by signal: %s",
+ g_strsignal (WTERMSIG (status)));
+
+ return FALSE;
+ }
+ else
+ {
+ /* This shouldn't happen */
+ g_set_error (err,
+ G_FILE_ERROR,
+ G_FILE_ERROR_FAILED,
+ "Could not change file mode: Child terminated abnormally");
+ return FALSE;
+ }
+ }
+#endif
+}
+
+static gchar *
+write_to_temp_file (const gchar *contents,
+ gssize length,
+ const gchar *template,
+ GError **err)
+{
+ gchar *tmp_name;
+ gchar *display_name;
+ gchar *retval;
+ FILE *file;
+ gint fd;
+ int save_errno;
+
+ retval = NULL;
+
+ tmp_name = g_strdup_printf ("%s.XXXXXX", template);
+
+ errno = 0;
+ fd = g_mkstemp (tmp_name);
+ save_errno = errno;
+ display_name = g_filename_display_name (tmp_name);
+
+ if (fd == -1)
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (save_errno),
+ "Failed to create file '%s': %s",
+ display_name, g_strerror (save_errno));
+
+ goto out;
+ }
+
+ if (!set_umask_permissions (fd, err))
+ {
+ close (fd);
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+
+ errno = 0;
+ file = fdopen (fd, "wb");
+ if (!file)
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Failed to open file '%s' for writing: fdopen() failed: %s",
+ display_name,
+ g_strerror (errno));
+
+ close (fd);
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+
+ if (length > 0)
+ {
+ size_t n_written;
+
+ errno = 0;
+
+ n_written = fwrite (contents, 1, length, file);
+
+ if (n_written < length)
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Failed to write file '%s': fwrite() failed: %s",
+ display_name,
+ g_strerror (errno));
+
+ fclose (file);
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+ }
+
+ errno = 0;
+ if (fclose (file) == EOF)
+ {
+ g_set_error (err,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Failed to close file '%s': fclose() failed: %s",
+ display_name,
+ g_strerror (errno));
+
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+
+ retval = g_strdup (tmp_name);
+
+ out:
+ g_free (tmp_name);
+ g_free (display_name);
+
+ return retval;
+}
+
+static gboolean
+file_replace (const gchar *filename,
+ const gchar *contents,
+ gssize length,
+ GError **error)
+{
+ gchar *tmp_filename;
+ gboolean retval;
+ GError *rename_error = NULL;
+
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (contents != NULL || length == 0, FALSE);
+ g_return_val_if_fail (length >= -1, FALSE);
+
+ if (length == -1)
+ length = strlen (contents);
+
+ tmp_filename = write_to_temp_file (contents, length, filename, error);
+
+ if (!tmp_filename)
+ {
+ retval = FALSE;
+ goto out;
+ }
+
+ if (!rename_file (tmp_filename, filename, &rename_error))
+ {
+#ifndef G_OS_WIN32
+
+ g_unlink (tmp_filename);
+ g_propagate_error (error, rename_error);
+ retval = FALSE;
+ goto out;
+
+#else /* G_OS_WIN32 */
+
+ /* Renaming failed, but on Windows this may just mean
+ * the file already exists. So if the target file
+ * exists, try deleting it and do the rename again.
+ */
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+ {
+ g_unlink (tmp_filename);
+ g_propagate_error (error, rename_error);
+ retval = FALSE;
+ goto out;
+ }
+
+ g_error_free (rename_error);
+
+ if (g_unlink (filename) == -1)
+ {
+ gchar *display_filename = g_filename_display_name (filename);
+
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Existing file '%s' could not be removed: g_unlink() failed: %s",
+ display_filename,
+ g_strerror (errno));
+
+ g_free (display_filename);
+ g_unlink (tmp_filename);
+ retval = FALSE;
+ goto out;
+ }
+
+ if (!rename_file (tmp_filename, filename, error))
+ {
+ g_unlink (tmp_filename);
+ retval = FALSE;
+ goto out;
+ }
+
+#endif
+ }
+
+ retval = TRUE;
+
+ out:
+ g_free (tmp_filename);
+ return retval;
+}
+
diff --git a/sfile.h b/sfile.h
new file mode 100644
index 0000000..92a1810
--- /dev/null
+++ b/sfile.h
@@ -0,0 +1,143 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+typedef struct SFormat SFormat;
+typedef struct SFileInput SFileInput;
+typedef struct SFileOutput SFileOutput;
+typedef guint SType;
+
+
+/* A possibly better API/naming scheme
+ *
+ * Serializer *serializer_new (SerializerFormat *format);
+ *
+ * SerializerReadContext *serializer_begin_read_filename (serializer *serialize,
+ * const char *filename,
+ * GError *err);
+ * serializer_get_blah (SerializerReadContext *);
+ * void serialzier_end_read (...);
+ *
+ * SerializerWritecontext *...;
+ * serializer_begin_write (context);
+ * serializer_write_int ();
+ * serializer_end_write (..., GError **err);
+ *
+ *
+ * For formats consider:
+ *
+ * Format *format_new (void);
+ * void format_set_record (Format *f, Content *r);
+ * Content *new_record (Content *c1, ...);
+ *
+ * List *format_new_list (Format *f
+ *
+ *
+ * Consider adding optional elements:
+ *
+ * sformat_new_optional (gpointer content)
+ *
+ * enums, optionals, selections, empties
+ *
+ *
+ *==============================================
+ * Also think about versioning - apps will want to be able to read and write
+ * different versions of the format, and they want to be able to sniff the
+ * format + version
+ *
+ */
+
+/* - Describing Types - */
+SFormat *sformat_new (gpointer f);
+gpointer sformat_new_record (const char *name,
+ SType *type,
+ gpointer content,
+ ...);
+gpointer sformat_new_list (const char *name,
+ SType *type,
+ gpointer content);
+gpointer sformat_new_pointer (const char *name,
+ SType *target_type);
+gpointer sformat_new_integer (const char *name);
+gpointer sformat_new_string (const char *name);
+void sformat_free (SFormat *format);
+
+
+/* - Reading - */
+SFileInput * sfile_load (const char *filename,
+ SFormat *format,
+ GError **err);
+void sfile_begin_get_record (SFileInput *file,
+ const char *name);
+int sfile_begin_get_list (SFileInput *file,
+ const char *name);
+void sfile_get_pointer (SFileInput *file,
+ const char *name,
+ gpointer *pointer);
+void sfile_get_integer (SFileInput *file,
+ const char *name,
+ gint32 *integer);
+void sfile_get_string (SFileInput *file,
+ const char *name,
+ char **string);
+void sfile_end_get (SFileInput *file,
+ const char *name,
+ gpointer object);
+void sfile_input_free (SFileInput *file);
+
+#if 0
+/* incremental loading (worth considering at least) */
+SFileLoader *sfile_loader_new (SFormat *format);
+void sfile_loader_add_text (SFileLoader *loader,
+ const char *text,
+ int len);
+SFile * sfile_loader_finish (SFileLoader *loader,
+ GError **err);
+void sfile_loader_free (SFileLoader *loader);
+#endif
+
+/* - Writing - */
+
+/* FIXME - not10: see if we can't get rid of the names. It
+ * should be possible to pass NULL to state_transition_check()
+ * and have it interprete that as "whatever". We would need
+ * a way to get the name back then, though.
+ */
+
+SFileOutput * sfile_output_new (SFormat *format);
+void sfile_begin_add_record (SFileOutput *file,
+ const char *name);
+void sfile_begin_add_list (SFileOutput *file,
+ const char *name);
+void sfile_end_add (SFileOutput *file,
+ const char *name,
+ gpointer object);
+void sfile_add_string (SFileOutput *file,
+ const char *name,
+ const char *string);
+void sfile_add_integer (SFileOutput *file,
+ const char *name,
+ int integer);
+void sfile_add_pointer (SFileOutput *file,
+ const char *name,
+ gpointer pointer);
+gboolean sfile_output_save (SFileOutput *sfile,
+ const char *filename,
+ GError **err);
+
+void sfile_output_free (SFileOutput *sfile);
diff --git a/stackstash.c b/stackstash.c
new file mode 100644
index 0000000..9f66f15
--- /dev/null
+++ b/stackstash.c
@@ -0,0 +1,218 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stackstash.h"
+
+typedef struct StackNode StackNode;
+
+struct StackNode
+{
+ StackNode * parent;
+ gpointer address;
+ StackNode * siblings;
+ StackNode * children;
+ StackNode * next; /* next leaf with the same pid */
+ int size;
+};
+
+struct StackStash
+{
+ StackNode *root;
+ GHashTable *leaves_by_process;
+};
+
+static StackNode *
+stack_node_new (void)
+{
+ StackNode *node = g_new (StackNode, 1);
+ node->siblings = NULL;
+ node->children = NULL;
+ node->address = NULL;
+ node->parent = NULL;
+ node->next = NULL;
+ node->size = 0;
+ return node;
+}
+
+static void
+stack_node_destroy (gpointer p)
+{
+ StackNode *node = p;
+ if (node)
+ {
+ stack_node_destroy (node->siblings);
+ stack_node_destroy (node->children);
+ g_free (node);
+ }
+}
+
+/* Stach */
+StackStash *
+stack_stash_new (void)
+{
+ StackStash *stash = g_new (StackStash, 1);
+
+ stash->leaves_by_process =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ stash->root = NULL;
+ return stash;
+}
+
+static StackNode *
+stack_node_add_trace (StackNode *node,
+ GList *bottom,
+ gint size,
+ StackNode **leaf)
+{
+ StackNode *match;
+ StackNode *n;
+
+ if (!bottom)
+ {
+ *leaf = NULL;
+ return node;
+ }
+
+ if (!bottom->next)
+ {
+ /* A leaf must always be separate, so pids can
+ * point to them
+ */
+ match = NULL;
+ }
+ else
+ {
+ for (match = node; match != NULL; match = match->siblings)
+ {
+ if (match->address == bottom->data)
+ break;
+ }
+ }
+
+ if (!match)
+ {
+ match = stack_node_new ();
+ match->address = bottom->data;
+ match->siblings = node;
+ node = match;
+ }
+
+ match->children =
+ stack_node_add_trace (match->children, bottom->next, size, leaf);
+
+ for (n = match->children; n; n = n->siblings)
+ n->parent = match;
+
+ if (!bottom->next)
+ {
+ match->size += size;
+ *leaf = match;
+ }
+
+ return node;
+}
+
+void
+stack_stash_add_trace (StackStash *stash,
+ Process *process,
+ gulong *addrs,
+ int n_addrs,
+ int size)
+{
+ GList *trace;
+ StackNode *leaf;
+ int i;
+
+ if (!n_addrs)
+ return;
+
+ trace = NULL;
+ for (i = 0; i < n_addrs; ++i)
+ trace = g_list_prepend (trace, GINT_TO_POINTER (addrs[i]));
+
+ stash->root = stack_node_add_trace (stash->root, trace, size, &leaf);
+
+ leaf->next = g_hash_table_lookup (
+ stash->leaves_by_process, process);
+ g_hash_table_insert (
+ stash->leaves_by_process, process, leaf);
+
+ g_list_free (trace);
+}
+
+typedef struct CallbackInfo
+{
+ StackFunction func;
+ gpointer data;
+} CallbackInfo;
+
+static void
+do_callback (gpointer key, gpointer value, gpointer data)
+{
+ CallbackInfo *info = data;
+ Process *process = key;
+ StackNode *n;
+ StackNode *leaf = value;
+ while (leaf)
+ {
+ GSList *trace;
+
+ trace = NULL;
+ for (n = leaf; n; n = n->parent)
+ trace = g_slist_prepend (trace, n->address);
+
+ info->func (process, trace, leaf->size, info->data);
+
+ g_slist_free (trace);
+
+ leaf = leaf->next;
+ }
+}
+
+void
+stack_stash_foreach (StackStash *stash,
+ StackFunction stack_func,
+ gpointer data)
+{
+ CallbackInfo info;
+ info.func = stack_func;
+ info.data = data;
+
+ g_hash_table_foreach (stash->leaves_by_process, do_callback, &info);
+}
+
+static void
+stack_node_free (StackNode *node)
+{
+ if (!node)
+ return;
+
+ stack_node_free (node->siblings);
+ stack_node_free (node->children);
+
+ g_free (node);
+}
+
+void
+stack_stash_free (StackStash *stash)
+{
+ stack_node_free (stash->root);
+ g_hash_table_destroy (stash->leaves_by_process);
+ g_free (stash);
+}
diff --git a/stackstash.h b/stackstash.h
new file mode 100644
index 0000000..aa058e1
--- /dev/null
+++ b/stackstash.h
@@ -0,0 +1,45 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef STACK_STASH_H
+#define STACK_STASH_H
+
+#include <glib.h>
+#include "process.h"
+
+typedef struct StackStash StackStash;
+
+typedef void (* StackFunction) (Process *process,
+ GSList *trace,
+ gint size,
+ gpointer data);
+
+/* Stach */
+StackStash *stack_stash_new (void);
+void stack_stash_add_trace (StackStash *stash,
+ Process *process,
+ gulong *addrs,
+ gint n_addrs,
+ int size);
+void stack_stash_foreach (StackStash *stash,
+ StackFunction stack_func,
+ gpointer data);
+void stack_stash_free (StackStash *stash);
+
+#endif
diff --git a/sysprof-icon.png b/sysprof-icon.png
new file mode 100644
index 0000000..7325a21
--- /dev/null
+++ b/sysprof-icon.png
Binary files differ
diff --git a/sysprof.c b/sysprof.c
new file mode 100644
index 0000000..ec73bc4
--- /dev/null
+++ b/sysprof.c
@@ -0,0 +1,1559 @@
+/* Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, Red Hat, Inc.
+ * Copyright 2004, 2005, 2006, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glade/glade.h>
+#include <errno.h>
+#include <glib/gprintf.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "binfile.h"
+#include "watch.h"
+#include "module/sysprof-module.h"
+#include "stackstash.h"
+#include "profile.h"
+#include "treeviewutils.h"
+
+/* FIXME - not10 */
+#define _(a) a
+
+#define APPLICATION_NAME "System Profiler"
+
+typedef struct Application Application;
+
+typedef enum
+{
+ INITIAL,
+ DISPLAYING,
+ PROFILING
+} State;
+
+struct Application
+{
+ int input_fd;
+ State state;
+ StackStash * stash;
+
+ GtkWidget * main_window;
+ GdkPixbuf * icon;
+
+ GtkTreeView * object_view;
+ GtkTreeView * callers_view;
+ GtkTreeView * descendants_view;
+
+ GtkWidget * start_button;
+ GtkWidget * profile_button;
+ GtkWidget * reset_button;
+ GtkWidget * save_as_button;
+ GtkWidget * dummy_button;
+
+ GtkWidget * start_item;
+ GtkWidget * profile_item;
+ GtkWidget * reset_item;
+ GtkWidget * save_as_item;
+ GtkWidget * open_item;
+
+ GtkWidget * samples_label;
+
+ Profile * profile;
+ ProfileDescendant * descendants;
+ ProfileCaller * callers;
+
+ int n_samples;
+
+ int timeout_id;
+ int generating_profile;
+
+ char * loaded_profile;
+
+ gboolean profile_from_file; /* FIXME - not10: This is a kludge. Figure out how
+ * to maintain the application model properly
+ *
+ * The fundamental issue is that the state of
+ * widgets is controlled by two different
+ * entities:
+ *
+ * The user clicks on them, changing their
+ * state.
+ *
+ * The application model changes, changing their
+ * state.
+ *
+ * Model/View/Controller is a possibility.
+ */
+ GTimeVal latest_reset;
+};
+
+static gboolean
+show_samples_timeout (gpointer data)
+{
+ Application *app = data;
+ char *label;
+
+ switch (app->state)
+ {
+ case INITIAL:
+ label = g_strdup ("Samples: 0");
+ break;
+
+ case PROFILING:
+ case DISPLAYING:
+ label = g_strdup_printf ("Samples: %d", app->n_samples);
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ gtk_label_set_label (GTK_LABEL (app->samples_label), label);
+
+ g_free (label);
+
+ app->timeout_id = 0;
+
+ return FALSE;
+}
+
+static void
+queue_show_samples (Application *app)
+{
+ if (!app->timeout_id)
+ app->timeout_id = g_timeout_add (225, show_samples_timeout, app);
+}
+
+static void
+update_sensitivity (Application *app)
+{
+ gboolean sensitive_profile_button;
+ gboolean sensitive_save_as_button;
+ gboolean sensitive_start_button;
+ gboolean sensitive_tree_views;
+ gboolean sensitive_samples_label;
+ gboolean sensitive_reset_button;
+
+ GtkWidget *active_radio_button;
+
+ switch (app->state)
+ {
+ case INITIAL:
+ sensitive_profile_button = FALSE;
+ sensitive_save_as_button = FALSE;
+ sensitive_start_button = TRUE;
+ sensitive_reset_button = FALSE;
+ sensitive_tree_views = FALSE;
+ sensitive_samples_label = FALSE;
+ active_radio_button = app->dummy_button;
+ break;
+
+ case PROFILING:
+ sensitive_profile_button = (app->n_samples > 0);
+ sensitive_save_as_button = (app->n_samples > 0);
+ sensitive_reset_button = (app->n_samples > 0);
+ sensitive_start_button = TRUE;
+ sensitive_tree_views = FALSE;
+ sensitive_samples_label = TRUE;
+ active_radio_button = app->start_button;
+ break;
+
+ case DISPLAYING:
+ sensitive_profile_button = TRUE;
+ sensitive_save_as_button = TRUE;
+ sensitive_start_button = TRUE;
+ sensitive_tree_views = TRUE;
+ sensitive_reset_button = TRUE;
+ sensitive_samples_label = FALSE;
+ active_radio_button = app->profile_button;
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (active_radio_button), TRUE);
+
+ /* "profile" widgets */
+ gtk_widget_set_sensitive (GTK_WIDGET (app->profile_button),
+ sensitive_profile_button);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->profile_item),
+ sensitive_profile_button);
+
+ /* "save as" widgets */
+ gtk_widget_set_sensitive (GTK_WIDGET (app->save_as_button),
+ sensitive_save_as_button);
+ gtk_widget_set_sensitive (app->save_as_item,
+ sensitive_save_as_button);
+
+ /* "start" widgets */
+ gtk_widget_set_sensitive (GTK_WIDGET (app->start_button),
+ sensitive_start_button);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->start_item),
+ sensitive_start_button);
+
+#if 0
+ /* FIXME - not10: gtk+ doesn't handle changes in sensitivity in response
+ * to a click on the same button very well
+ */
+ gtk_widget_set_sensitive (GTK_WIDGET (app->reset_button),
+ sensitive_reset_button);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->reset_item),
+ sensitive_reset_button);
+#endif
+
+ gtk_widget_set_sensitive (GTK_WIDGET (app->object_view), sensitive_tree_views);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->callers_view), sensitive_tree_views);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->descendants_view), sensitive_tree_views);
+ gtk_widget_set_sensitive (GTK_WIDGET (app->samples_label), sensitive_samples_label);
+
+ queue_show_samples (app);
+}
+
+static void
+set_busy (GtkWidget *widget, gboolean busy)
+{
+ GdkCursor *cursor;
+
+ if (busy)
+ cursor = gdk_cursor_new (GDK_WATCH);
+ else
+ cursor = NULL;
+
+ gdk_window_set_cursor (widget->window, cursor);
+
+ if (cursor)
+ gdk_cursor_unref (cursor);
+
+ gdk_flush ();
+}
+
+#if 0
+static gchar *
+get_name (pid_t pid)
+{
+ char *cmdline;
+ char *name = g_strdup_printf ("/proc/%d/cmdline", pid);
+
+ if (g_file_get_contents (name, &cmdline, NULL, NULL))
+ return cmdline;
+ else
+ return g_strdup ("<unknown>");
+}
+#endif
+
+#if 0
+static void
+on_timeout (gpointer data)
+{
+ Application *app = data;
+ GList *pids, *list;
+ int mypid = getpid();
+
+ pids = list_processes ();
+
+ for (list = pids; list != NULL; list = list->next)
+ {
+ int pid = GPOINTER_TO_INT (list->data);
+
+ if (pid == mypid)
+ continue;
+
+ if (get_process_state (pid) == PROCESS_RUNNING)
+ {
+ Process *process;
+ SysprofStackTrace trace;
+ int i;
+
+ if (!generate_stack_trace (pid, &trace))
+ {
+ continue;
+ }
+
+ process = process_get_from_pid (pid);
+
+#if 0
+ process_ensure_map (process, trace.pid,
+ (gulong)trace.addresses[i]);
+#endif
+
+ g_print ("n addr: %d\n", trace.n_addresses);
+ for (i = 0; i < trace.n_addresses; ++i)
+ process_ensure_map (process, trace.pid,
+ (gulong)trace.addresses[i]);
+ g_assert (!app->generating_profile);
+
+ stack_stash_add_trace (
+ app->stash, process,
+ (gulong *)trace.addresses, trace.n_addresses, 1);
+
+ app->n_samples++;
+ }
+ }
+
+ update_sensitivity (app);
+ g_list_free (pids);
+
+ return TRUE;
+}
+#endif
+
+static double
+timeval_to_ms (const GTimeVal *timeval)
+{
+ return (timeval->tv_sec * G_USEC_PER_SEC + timeval->tv_usec) / 1000.0;
+}
+
+static double
+time_diff (const GTimeVal *first,
+ const GTimeVal *second)
+{
+ double first_ms = timeval_to_ms (first);
+ double second_ms = timeval_to_ms (second);
+
+ return first_ms - second_ms;
+}
+
+#define RESET_DEAD_PERIOD 250
+
+static void
+on_read (gpointer data)
+{
+ Application *app = data;
+ SysprofStackTrace trace;
+ GTimeVal now;
+ int rd;
+
+ rd = read (app->input_fd, &trace, sizeof (trace));
+
+ if (app->state != PROFILING)
+ return;
+
+ if (rd == -1 && errno == EWOULDBLOCK)
+ return;
+
+ g_get_current_time (&now);
+
+ /* After a reset we ignore samples for a short period so that
+ * a reset will actually cause 'samples' to become 0
+ */
+ if (time_diff (&now, &app->latest_reset) < RESET_DEAD_PERIOD)
+ return;
+
+#if 0
+ int i;
+ g_print ("pid: %d\n", trace.pid);
+ for (i=0; i < trace.n_addresses; ++i)
+ g_print ("rd: %08x\n", trace.addresses[i]);
+ g_print ("-=-\n");
+#endif
+
+ if (rd > 0 && !app->generating_profile && trace.n_addresses)
+ {
+ Process *process = process_get_from_pid (trace.pid);
+ int i;
+/* char *filename = NULL; */
+
+/* if (*trace.filename) */
+/* filename = trace.filename; */
+
+ for (i = 0; i < trace.n_addresses; ++i)
+ {
+ process_ensure_map (process, trace.pid,
+ (gulong)trace.addresses[i]);
+ }
+ g_assert (!app->generating_profile);
+
+ stack_stash_add_trace (
+ app->stash, process,
+ (gulong *)trace.addresses, trace.n_addresses, 1);
+
+ app->n_samples++;
+ }
+
+ update_sensitivity (app);
+}
+
+static void
+set_application_title (Application *app,
+ const char * name)
+{
+ char *new_name;
+ if (name)
+ new_name = g_path_get_basename (name);
+ else
+ new_name = NULL;
+
+ if (app->loaded_profile)
+ g_free (app->loaded_profile);
+
+ app->loaded_profile = new_name;
+
+ if (app->loaded_profile)
+ {
+ gtk_window_set_title (GTK_WINDOW (app->main_window),
+ app->loaded_profile);
+ }
+ else
+ {
+ gtk_window_set_title (GTK_WINDOW (app->main_window),
+ "System Profiler");
+ }
+}
+
+static void
+delete_data (Application *app)
+{
+ if (app->profile)
+ {
+ profile_free (app->profile);
+ app->profile = NULL;
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (app->object_view), NULL);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (app->callers_view), NULL);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (app->descendants_view), NULL);
+ }
+
+ if (app->stash)
+ stack_stash_free (app->stash);
+ app->stash = stack_stash_new ();
+ process_flush_caches ();
+ app->n_samples = 0;
+ queue_show_samples (app);
+ app->profile_from_file = FALSE;
+ set_application_title (app, NULL);
+ g_get_current_time (&app->latest_reset);
+}
+
+static void
+empty_file_descriptor (Application *app)
+{
+ int rd;
+ SysprofStackTrace trace;
+
+ do
+ {
+ rd = read (app->input_fd, &trace, sizeof (trace));
+
+ } while (rd != -1); /* until EWOULDBLOCK */
+}
+
+static gboolean
+start_profiling (gpointer data)
+{
+ Application *app = data;
+
+ app->state = PROFILING;
+
+ update_sensitivity (app);
+
+ /* Make sure samples generated between 'start clicked' and now
+ * are deleted
+ */
+ empty_file_descriptor (app);
+
+ return FALSE;
+}
+
+static void
+sorry (GtkWidget *parent_window,
+ const gchar *format,
+ ...)
+{
+ va_list args;
+ char *message;
+ GtkWidget *dialog;
+
+ va_start (args, format);
+ g_vasprintf (&message, format, args);
+ va_end (args);
+
+ dialog = gtk_message_dialog_new (parent_window ? GTK_WINDOW (parent_window) : NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK, message);
+ g_free (message);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), APPLICATION_NAME " Warning");
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+static gboolean
+load_module (void)
+{
+ int exit_status = -1;
+ char *dummy1, *dummy2;
+
+ if (g_spawn_command_line_sync ("/sbin/modprobe sysprof-module",
+ &dummy1, &dummy2,
+ &exit_status,
+ NULL))
+ {
+ if (WIFEXITED (exit_status))
+ exit_status = WEXITSTATUS (exit_status);
+
+ g_free (dummy1);
+ g_free (dummy2);
+ }
+
+ return (exit_status == 0);
+}
+
+static void
+on_menu_item_activated (GtkWidget *menu_item, GtkWidget *tool_button)
+{
+ GtkToggleToolButton *button = GTK_TOGGLE_TOOL_BUTTON (tool_button);
+
+ if (!gtk_toggle_tool_button_get_active (button))
+ gtk_toggle_tool_button_set_active (button, TRUE);
+}
+
+static void
+on_start_toggled (GtkWidget *widget, gpointer data)
+{
+ Application *app = data;
+
+ if (!gtk_toggle_tool_button_get_active (
+ GTK_TOGGLE_TOOL_BUTTON (app->start_button)))
+ return;
+
+ if (app->input_fd == -1)
+ {
+ int fd;
+
+ fd = open ("/proc/sysprof-trace", O_RDONLY);
+ if (fd < 0)
+ {
+ load_module();
+
+ fd = open ("/proc/sysprof-trace", O_RDONLY);
+
+ if (fd < 0)
+ {
+ sorry (app->main_window,
+ "Can't open /proc/sysprof-trace. You need to insert\n"
+ "the sysprof kernel module. Run\n"
+ "\n"
+ " modprobe sysprof-module\n"
+ "\n"
+ "as root.");
+
+ update_sensitivity (app);
+ return;
+ }
+ }
+
+ app->input_fd = fd;
+ fd_add_watch (app->input_fd, app);
+ }
+
+ fd_set_read_callback (app->input_fd, on_read);
+
+ delete_data (app);
+
+ g_idle_add_full (G_PRIORITY_LOW, start_profiling, app, NULL);
+}
+
+enum
+{
+ OBJECT_NAME,
+ OBJECT_SELF,
+ OBJECT_TOTAL,
+ OBJECT_OBJECT
+};
+
+enum
+{
+ CALLERS_NAME,
+ CALLERS_SELF,
+ CALLERS_TOTAL,
+ CALLERS_OBJECT
+};
+
+enum
+{
+ DESCENDANTS_NAME,
+ DESCENDANTS_SELF,
+ DESCENDANTS_NON_RECURSE,
+ DESCENDANTS_TOTAL,
+ DESCENDANTS_OBJECT
+};
+
+static ProfileObject *
+get_current_object (Application *app)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter selected;
+ ProfileObject *object;
+
+ selection = gtk_tree_view_get_selection (app->object_view);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &selected))
+ {
+ gtk_tree_model_get (model, &selected,
+ OBJECT_OBJECT, &object,
+ -1);
+ return object;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static void
+fill_main_list (Application *app)
+{
+ GList *list;
+ GtkListStore *list_store;
+ Profile *profile = app->profile;
+ GList *objects;
+
+ if (profile)
+ {
+ gpointer sort_state;
+
+ list_store = gtk_list_store_new (4,
+ G_TYPE_STRING,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+
+ objects = profile_get_objects (profile);
+ for (list = objects; list != NULL; list = list->next)
+ {
+ ProfileObject *object = list->data;
+ GtkTreeIter iter;
+ double profile_size = profile_get_size (profile);
+
+ gtk_list_store_append (list_store, &iter);
+
+ gtk_list_store_set (list_store, &iter,
+ OBJECT_NAME, object->name,
+ OBJECT_SELF, 100.0 * object->self / profile_size,
+ OBJECT_TOTAL, 100.0 * object->total / profile_size,
+ OBJECT_OBJECT, object,
+ -1);
+ }
+ g_list_free (objects);
+
+ sort_state = save_sort_state (app->object_view);
+
+ gtk_tree_view_set_model (app->object_view, GTK_TREE_MODEL (list_store));
+
+ if (sort_state)
+ {
+ restore_sort_state (app->object_view, sort_state);
+ }
+ else
+ {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
+ OBJECT_TOTAL,
+ GTK_SORT_DESCENDING);
+ }
+
+ g_object_unref (G_OBJECT (list_store));
+ }
+
+ gtk_tree_view_columns_autosize (app->object_view);
+}
+
+static void
+add_node (GtkTreeStore *store,
+ int size,
+ const GtkTreeIter *parent,
+ ProfileDescendant *node)
+{
+ GtkTreeIter iter;
+
+ if (!node)
+ return;
+
+ gtk_tree_store_insert (store, &iter, (GtkTreeIter *)parent, 0);
+
+ gtk_tree_store_set (store, &iter,
+ DESCENDANTS_NAME, node->object->name,
+ DESCENDANTS_SELF, 100 * (node->self)/(double)size,
+ DESCENDANTS_NON_RECURSE, 100 * (node->non_recursion)/(double)size,
+ DESCENDANTS_TOTAL, 100 * (node->total)/(double)size,
+ DESCENDANTS_OBJECT, node->object,
+ -1);
+
+ add_node (store, size, parent, node->siblings);
+ add_node (store, size, &iter, node->children);
+}
+
+static void
+fill_descendants_tree (Application *app)
+{
+ GtkTreeStore *tree_store;
+ gpointer sort_state;
+
+ sort_state = save_sort_state (app->descendants_view);
+
+ if (app->descendants)
+ {
+ profile_descendant_free (app->descendants);
+ app->descendants = NULL;
+ }
+
+ tree_store =
+ gtk_tree_store_new (5,
+ G_TYPE_STRING,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+
+ if (app->profile)
+ {
+ ProfileObject *object = get_current_object (app);
+ if (object)
+ {
+ app->descendants =
+ profile_create_descendants (app->profile, object);
+ add_node (tree_store,
+ profile_get_size (app->profile), NULL, app->descendants);
+ }
+ }
+
+ gtk_tree_view_set_model (
+ app->descendants_view, GTK_TREE_MODEL (tree_store));
+
+ g_object_unref (G_OBJECT (tree_store));
+
+ if (!sort_state)
+ {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree_store),
+ DESCENDANTS_NON_RECURSE,
+ GTK_SORT_DESCENDING);
+ }
+ else
+ {
+ restore_sort_state (app->descendants_view, sort_state);
+ }
+
+ gtk_tree_view_columns_autosize (app->descendants_view);
+}
+
+static void
+add_callers (GtkListStore *list_store,
+ Profile *profile,
+ ProfileCaller *callers)
+{
+ while (callers)
+ {
+ gchar *name;
+ GtkTreeIter iter;
+ double profile_size = profile_get_size (profile);
+
+ if (callers->object)
+ name = callers->object->name;
+ else
+ name = "<spontaneous>";
+
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (
+ list_store, &iter,
+ CALLERS_NAME, name,
+ CALLERS_SELF, 100.0 * callers->self / profile_size,
+ CALLERS_TOTAL, 100.0 * callers->total / profile_size,
+ CALLERS_OBJECT, callers->object,
+ -1);
+
+ callers = callers->next;
+ }
+}
+
+static void
+fill_callers_list (Application *app)
+{
+ GtkListStore *list_store;
+ gpointer sort_state;
+
+ sort_state = save_sort_state (app->descendants_view);
+
+ if (app->callers)
+ {
+ profile_caller_free (app->callers);
+ app->callers = NULL;
+ }
+
+ list_store =
+ gtk_list_store_new (4,
+ G_TYPE_STRING,
+ G_TYPE_DOUBLE,
+ G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+
+ if (app->profile)
+ {
+ ProfileObject *object = get_current_object (app);
+ if (object)
+ {
+ app->callers = profile_list_callers (app->profile, object);
+ add_callers (list_store, app->profile, app->callers);
+ }
+ }
+
+ gtk_tree_view_set_model (
+ app->callers_view, GTK_TREE_MODEL (list_store));
+
+ g_object_unref (G_OBJECT (list_store));
+
+ if (!sort_state)
+ {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
+ CALLERS_TOTAL,
+ GTK_SORT_DESCENDING);
+ }
+ else
+ {
+ restore_sort_state (app->callers_view, sort_state);
+ }
+
+ gtk_tree_view_columns_autosize (app->callers_view);
+}
+
+static void
+fill_lists (Application *app)
+{
+ fill_main_list (app);
+ fill_callers_list (app);
+ fill_descendants_tree (app);
+}
+
+static void
+ensure_profile (Application *app)
+{
+ if (app->profile)
+ return;
+
+ app->profile = profile_new (app->stash);
+
+ fill_lists (app);
+
+ app->state = DISPLAYING;
+
+ update_sensitivity (app);
+}
+
+static void
+on_about_activated (GtkWidget *widget, gpointer data)
+{
+#define OSLASH "\303\270"
+ Application *app = data;
+
+ gtk_show_about_dialog (GTK_WINDOW (app->main_window),
+ "logo", app->icon,
+ "name", APPLICATION_NAME,
+ "copyright", "Copyright 2004-2006, S"OSLASH"ren Sandmann",
+ "version", PACKAGE_VERSION,
+ NULL);
+}
+
+static void
+on_profile_toggled (GtkWidget *widget, gpointer data)
+{
+ Application *app = data;
+
+ if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (app->profile_button)))
+ {
+ set_busy (app->main_window, TRUE);
+ if (app->profile && !app->profile_from_file)
+ {
+ profile_free (app->profile);
+ app->profile = NULL;
+ }
+
+ ensure_profile (app);
+ set_busy (app->main_window, FALSE);
+ }
+}
+
+static void
+on_reset_clicked (gpointer widget, gpointer data)
+{
+ Application *app = data;
+
+ set_busy (app->main_window, TRUE);
+
+ delete_data (app);
+
+ if (app->state == DISPLAYING)
+ app->state = INITIAL;
+
+ update_sensitivity (app);
+
+ set_busy (app->main_window, FALSE);
+}
+
+static gboolean
+overwrite_file (GtkWindow *window,
+ const char *filename)
+{
+ GtkWidget *msgbox;
+ gchar *utf8_file_name;
+ AtkObject *obj;
+ gint ret;
+
+ utf8_file_name = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
+ msgbox = gtk_message_dialog_new (window,
+ (GtkDialogFlags)GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("A file named \"%s\" already exists."),
+ utf8_file_name);
+ g_free (utf8_file_name);
+
+ gtk_message_dialog_format_secondary_text (
+ GTK_MESSAGE_DIALOG (msgbox),
+ _("Do you want to replace it with the one you are saving?"));
+
+ gtk_dialog_add_button (GTK_DIALOG (msgbox),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_add_button (GTK_DIALOG (msgbox),
+ _("_Replace"), GTK_RESPONSE_YES);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (msgbox),
+ GTK_RESPONSE_CANCEL);
+
+ obj = gtk_widget_get_accessible (msgbox);
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ atk_object_set_name (obj, _("Question"));
+
+ ret = gtk_dialog_run (GTK_DIALOG (msgbox));
+ gtk_widget_destroy (msgbox);
+
+ return (ret == GTK_RESPONSE_YES);
+
+}
+
+static void
+on_save_as_clicked (gpointer widget,
+ gpointer data)
+{
+ Application *app = data;
+ GtkWidget *dialog;
+
+ ensure_profile (app);
+
+ set_busy (app->main_window, TRUE);
+
+ dialog = gtk_file_chooser_dialog_new ("Save As",
+ GTK_WINDOW (app->main_window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ set_busy (app->main_window, FALSE);
+
+ retry:
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ GError *err = NULL;
+ gchar *filename;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS) &&
+ !overwrite_file (GTK_WINDOW (app->main_window), filename))
+ {
+ g_free (filename);
+ goto retry;
+ }
+
+ set_busy (dialog, TRUE);
+ if (!profile_save (app->profile, filename, &err))
+ {
+ sorry (app->main_window, "Could not save %s: %s",
+ filename, err->message);
+
+ set_busy (dialog, FALSE);
+ g_free (filename);
+ goto retry;
+ }
+ set_application_title (app, filename);
+ set_busy (dialog, FALSE);
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+set_loaded_profile (Application *app,
+ const char *name,
+ Profile *profile)
+{
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (profile != NULL);
+
+ set_busy (app->main_window, TRUE);
+
+ delete_data (app);
+
+ app->state = DISPLAYING;
+
+ app->n_samples = profile_get_size (profile);
+
+ app->profile = profile;
+ app->profile_from_file = TRUE;
+
+ fill_lists (app);
+
+ set_application_title (app, name);
+
+ update_sensitivity (app);
+
+ set_busy (app->main_window, FALSE);
+}
+
+static void
+show_could_not_open (Application *app,
+ const char *filename,
+ GError *err)
+{
+ sorry (app->main_window,
+ "Could not open %s: %s",
+ filename,
+ err->message);
+}
+
+static void
+on_open_clicked (gpointer widget,
+ gpointer data)
+{
+ Application *app = data;
+ gchar *filename = NULL;
+ Profile *profile = NULL;
+ GtkWidget *dialog;
+
+ set_busy (app->main_window, TRUE);
+
+ dialog = gtk_file_chooser_dialog_new ("Open",
+ GTK_WINDOW (app->main_window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ set_busy (app->main_window, FALSE);
+
+ retry:
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ GError *err = NULL;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+ set_busy (dialog, TRUE);
+
+ profile = profile_load (filename, &err);
+
+ if (!profile)
+ {
+ set_busy (dialog, FALSE);
+
+ show_could_not_open (app, filename, err);
+ g_error_free (err);
+ g_free (filename);
+
+ filename = NULL;
+ goto retry;
+ }
+
+ set_busy (dialog, FALSE);
+ }
+
+ gtk_widget_destroy (dialog);
+
+ if (profile)
+ {
+ g_assert (filename);
+ set_loaded_profile (app, filename, profile);
+
+ g_free (filename);
+ }
+}
+
+static void
+on_delete (GtkWidget *window)
+{
+ gtk_main_quit ();
+}
+
+static void
+expand_descendants_tree (Application *app)
+{
+ GtkTreeModel *model = gtk_tree_view_get_model (app->descendants_view);
+ GtkTreeIter iter;
+ GList *all_paths = NULL;
+ int n_rows;
+ int max_rows = 40; /* FIXME */
+ double top_value = 0.0;
+ GtkTreePath *first_path;
+ GList *list;
+
+ first_path = gtk_tree_path_new_first();
+
+ all_paths = g_list_prepend (all_paths, first_path);
+
+ n_rows = 1;
+
+ gtk_tree_model_get_iter (model, &iter, first_path);
+ gtk_tree_model_get (model, &iter,
+ OBJECT_TOTAL, &top_value,
+ -1);
+
+ while (all_paths && n_rows < max_rows)
+ {
+ GtkTreeIter best_iter;
+ GtkTreePath *best_path;
+ double best_value;
+ int n_children;
+ int i;
+
+ best_value = 0.0;
+ best_path = NULL;
+
+ for (list = all_paths; list != NULL; list = list->next)
+ {
+ GtkTreePath *path = list->data;
+ GtkTreeIter iter;
+ double value;
+ g_assert (path != NULL);
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ gtk_tree_model_get (model, &iter,
+ OBJECT_TOTAL, &value,
+ -1);
+ }
+ if (value >= best_value)
+ {
+ best_value = value;
+ best_path = path;
+
+ gtk_tree_model_get_iter (model, &best_iter, path);
+ }
+ }
+
+ gtk_tree_model_get_iter (model, &iter, best_path);
+
+ n_children = gtk_tree_model_iter_n_children (model, &best_iter);
+
+ if (n_children && (best_value / top_value) > 0.04 &&
+ (n_children + gtk_tree_path_get_depth (best_path)) / (double)max_rows < (best_value / top_value) )
+ {
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (app->descendants_view), best_path, FALSE);
+ n_rows += n_children;
+
+ if (gtk_tree_path_get_depth (best_path) < 4)
+ {
+ GtkTreePath *path = gtk_tree_path_copy (best_path);
+ gtk_tree_path_down (path);
+
+ for (i = 0; i < n_children; ++i)
+ {
+ all_paths = g_list_prepend (all_paths, path);
+
+ path = gtk_tree_path_copy (path);
+ gtk_tree_path_next (path);
+ }
+ gtk_tree_path_free (path);
+ }
+ }
+
+ all_paths = g_list_remove (all_paths, best_path);
+ gtk_tree_path_free (best_path);
+ }
+
+ for (list = all_paths; list != NULL; list = list->next)
+ gtk_tree_path_free (list->data);
+
+ g_list_free (all_paths);
+}
+
+static void
+on_object_selection_changed (GtkTreeSelection *selection,
+ gpointer data)
+{
+ Application *app = data;
+
+ set_busy (app->main_window, TRUE);
+
+ gdk_window_process_all_updates ();
+
+ fill_descendants_tree (app);
+ fill_callers_list (app);
+
+ if (get_current_object (app))
+ expand_descendants_tree (app);
+
+ set_busy (app->main_window, FALSE);
+}
+
+static void
+really_goto_object (Application *app,
+ ProfileObject *object)
+{
+ GtkTreeModel *profile_objects;
+ GtkTreeIter iter;
+ gboolean found = FALSE;
+
+ profile_objects = gtk_tree_view_get_model (app->object_view);
+
+ if (gtk_tree_model_get_iter_first (profile_objects, &iter))
+ {
+ do
+ {
+ ProfileObject *profile_object;
+
+ gtk_tree_model_get (profile_objects, &iter,
+ OBJECT_OBJECT, &profile_object,
+ -1);
+
+ if (profile_object == object)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ while (gtk_tree_model_iter_next (profile_objects, &iter));
+ }
+
+ if (found)
+ {
+ GtkTreePath *path =
+ gtk_tree_model_get_path (profile_objects, &iter);
+
+ gtk_tree_view_set_cursor (app->object_view, path, 0, FALSE);
+ }
+}
+
+static void
+goto_object (Application *app,
+ GtkTreeView *tree_view,
+ GtkTreePath *path,
+ gint column)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+ ProfileObject *object;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (model, &iter, column, &object, -1);
+
+ if (!object)
+ return;
+
+ really_goto_object (app, object);
+
+}
+
+static void
+on_descendants_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer data)
+{
+ Application *app = data;
+
+ goto_object (app, tree_view, path, DESCENDANTS_OBJECT);
+
+ gtk_widget_grab_focus (GTK_WIDGET (app->descendants_view));
+}
+
+static void
+on_callers_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer data)
+{
+ Application *app = data;
+
+ goto_object (app, tree_view, path, CALLERS_OBJECT);
+
+ gtk_widget_grab_focus (GTK_WIDGET (app->callers_view));
+}
+
+static void
+set_sizes (GtkWindow *window,
+ GtkWidget *hpaned,
+ GtkWidget *vpaned)
+{
+ GdkScreen *screen;
+ int monitor_num;
+ GdkRectangle monitor;
+ int width, height;
+ GtkWidget *widget = GTK_WIDGET (window);
+
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
+
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ width = monitor.width * 3 / 4;
+ height = monitor.height * 3 / 4;
+
+ gtk_window_resize (window, width, height);
+
+ gtk_paned_set_position (GTK_PANED (vpaned), height / 2);
+ gtk_paned_set_position (GTK_PANED (hpaned), width / 2);
+}
+
+static void
+set_shadows (void)
+{
+ /* Get rid of motif out-bevels */
+ gtk_rc_parse_string (
+ "style \"blah\" "
+ "{ "
+ " GtkToolbar::shadow_type = none "
+ " GtkMenuBar::shadow_type = none "
+ " GtkMenuBar::internal_padding = 2 "
+ "} "
+ "widget \"*toolbar\" style : rc \"blah\"\n"
+ "widget \"*menubar\" style : rc \"blah\"\n"
+ );
+}
+
+static void
+build_gui (Application *app)
+{
+ GladeXML *xml;
+ GtkTreeSelection *selection;
+ GtkTreeViewColumn *col;
+
+ set_shadows ();
+
+ xml = glade_xml_new (DATADIR "/sysprof.glade", NULL, NULL);
+
+ /* Main Window */
+ app->main_window = glade_xml_get_widget (xml, "main_window");
+ app->icon = gdk_pixbuf_new_from_file (PIXMAPDIR "/sysprof-icon.png", NULL);
+
+ gtk_window_set_icon (GTK_WINDOW (app->main_window), app->icon);
+
+ g_signal_connect (G_OBJECT (app->main_window), "delete_event",
+ G_CALLBACK (on_delete), NULL);
+
+ gtk_widget_realize (GTK_WIDGET (app->main_window));
+ set_sizes (GTK_WINDOW (app->main_window),
+ glade_xml_get_widget (xml, "hpaned"),
+ glade_xml_get_widget (xml, "vpaned"));
+
+ /* Tool items */
+
+ app->start_button = glade_xml_get_widget (xml, "start_button");
+ app->profile_button = glade_xml_get_widget (xml, "profile_button");
+ app->reset_button = glade_xml_get_widget (xml, "reset_button");
+ app->save_as_button = glade_xml_get_widget (xml, "save_as_button");
+ app->dummy_button = glade_xml_get_widget (xml, "dummy_button");
+
+ gtk_toggle_tool_button_set_active (
+ GTK_TOGGLE_TOOL_BUTTON (app->profile_button), FALSE);
+
+ g_signal_connect (G_OBJECT (app->start_button), "toggled",
+ G_CALLBACK (on_start_toggled), app);
+
+ g_signal_connect (G_OBJECT (app->profile_button), "toggled",
+ G_CALLBACK (on_profile_toggled), app);
+
+ g_signal_connect (G_OBJECT (app->reset_button), "clicked",
+ G_CALLBACK (on_reset_clicked), app);
+
+ g_signal_connect (G_OBJECT (app->save_as_button), "clicked",
+ G_CALLBACK (on_save_as_clicked), app);
+
+
+ app->samples_label = glade_xml_get_widget (xml, "samples_label");
+
+ /* Menu items */
+ app->start_item = glade_xml_get_widget (xml, "start_item");
+ app->profile_item = glade_xml_get_widget (xml, "profile_item");
+ app->reset_item = glade_xml_get_widget (xml, "reset_item");
+ app->open_item = glade_xml_get_widget (xml, "open_item");
+ app->save_as_item = glade_xml_get_widget (xml, "save_as_item");
+
+ g_assert (app->start_item);
+ g_assert (app->profile_item);
+ g_assert (app->save_as_item);
+ g_assert (app->open_item);
+
+ g_signal_connect (G_OBJECT (app->start_item), "activate",
+ G_CALLBACK (on_menu_item_activated), app->start_button);
+
+ g_signal_connect (G_OBJECT (app->profile_item), "activate",
+ G_CALLBACK (on_menu_item_activated), app->profile_button);
+
+ g_signal_connect (G_OBJECT (app->reset_item), "activate",
+ G_CALLBACK (on_reset_clicked), app);
+
+ g_signal_connect (G_OBJECT (app->open_item), "activate",
+ G_CALLBACK (on_open_clicked), app);
+
+ g_signal_connect (G_OBJECT (app->save_as_item), "activate",
+ G_CALLBACK (on_save_as_clicked), app);
+
+ g_signal_connect (G_OBJECT (glade_xml_get_widget (xml, "quit")), "activate",
+ G_CALLBACK (on_delete), NULL);
+
+ g_signal_connect (G_OBJECT (glade_xml_get_widget (xml, "about")), "activate",
+ G_CALLBACK (on_about_activated), app);
+
+ /* TreeViews */
+
+ /* object view */
+ app->object_view = (GtkTreeView *)glade_xml_get_widget (xml, "object_view");
+ gtk_tree_view_set_enable_search (app->object_view, FALSE);
+ col = add_plain_text_column (app->object_view, _("Functions"), OBJECT_NAME);
+ add_double_format_column (app->object_view, _("Self"), OBJECT_SELF, "%.2f ");
+ add_double_format_column (app->object_view, _("Total"), OBJECT_TOTAL, "%.2f ");
+ selection = gtk_tree_view_get_selection (app->object_view);
+ g_signal_connect (selection, "changed", G_CALLBACK (on_object_selection_changed), app);
+ gtk_tree_view_column_set_expand (col, TRUE);
+
+ /* callers view */
+ app->callers_view = (GtkTreeView *)glade_xml_get_widget (xml, "callers_view");
+ gtk_tree_view_set_enable_search (app->callers_view, FALSE);
+ col = add_plain_text_column (app->callers_view, _("Callers"), CALLERS_NAME);
+ add_double_format_column (app->callers_view, _("Self"), CALLERS_SELF, "%.2f ");
+ add_double_format_column (app->callers_view, _("Total"), CALLERS_TOTAL, "%.2f ");
+ g_signal_connect (app->callers_view, "row-activated",
+ G_CALLBACK (on_callers_row_activated), app);
+ gtk_tree_view_column_set_expand (col, TRUE);
+
+ /* descendants view */
+ app->descendants_view = (GtkTreeView *)glade_xml_get_widget (xml, "descendants_view");
+ gtk_tree_view_set_enable_search (app->descendants_view, FALSE);
+ col = add_plain_text_column (app->descendants_view, _("Descendants"), DESCENDANTS_NAME);
+ add_double_format_column (app->descendants_view, _("Self"), DESCENDANTS_SELF, "%.2f ");
+ add_double_format_column (app->descendants_view, _("Cumulative"), DESCENDANTS_NON_RECURSE, "%.2f ");
+ g_signal_connect (app->descendants_view, "row-activated",
+ G_CALLBACK (on_descendants_row_activated), app);
+ gtk_tree_view_column_set_expand (col, TRUE);
+
+ gtk_widget_grab_focus (GTK_WIDGET (app->object_view));
+ gtk_widget_show_all (app->main_window);
+ gtk_widget_hide (app->dummy_button);
+
+ /* Statusbar */
+ queue_show_samples (app);
+}
+
+static Application *
+application_new (void)
+{
+ Application *app = g_new0 (Application, 1);
+
+ app->stash = stack_stash_new ();
+ app->input_fd = -1;
+ app->state = INITIAL;
+
+ g_get_current_time (&app->latest_reset);
+
+ return app;
+}
+
+typedef struct
+{
+ const char *filename;
+ Application *app;
+} FileOpenData;
+
+static gboolean
+load_file (gpointer data)
+{
+ FileOpenData *file_open_data = data;
+ const char *filename = file_open_data->filename;
+ Application *app = file_open_data->app;
+ GError *err = NULL;
+ Profile *profile;
+
+ set_busy (app->main_window, TRUE);
+
+ profile = profile_load (filename, &err);
+
+ set_busy (app->main_window, FALSE);
+
+ if (profile)
+ {
+ set_loaded_profile (app, filename, profile);
+ }
+ else
+ {
+ show_could_not_open (app, filename, err);
+ g_error_free (err);
+ }
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ Application *app;
+
+ gtk_init (&argc, &argv);
+
+ app = application_new ();
+
+#if 0
+ nice (-19);
+ g_timeout_add (10, on_timeout, app);
+#endif
+
+ build_gui (app);
+
+ update_sensitivity (app);
+
+ if (argc > 1)
+ {
+ FileOpenData *file_open_data = g_new0 (FileOpenData, 1);
+
+ file_open_data->filename = argv[1];
+ file_open_data->app = app;
+
+ g_idle_add (load_file, file_open_data);
+ }
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/sysprof.glade b/sysprof.glade
new file mode 100644
index 0000000..c68756e
--- /dev/null
+++ b/sysprof.glade
@@ -0,0 +1,565 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="main_window">
+ <property name="title" translatable="yes">System Profiler</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="default_width">700</property>
+ <property name="default_height">500</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+
+ <child>
+ <widget class="GtkVBox" id="main_vbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="menubar">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="open_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Open...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_open_item_activate" last_modification_time="Thu, 04 Nov 2004 21:01:03 GMT"/>
+ <accelerator key="o" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image80">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="save_as_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save _As...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_Save _As..._activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
+ <accelerator key="s" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image81">
+ <property name="visible">True</property>
+ <property name="stock">gtk-save-as</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Quit</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_quit_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
+ <accelerator key="q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image82">
+ <property name="visible">True</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_View</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem3_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="start_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Start</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_start1_activate" last_modification_time="Thu, 04 Nov 2004 18:51:54 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image83">
+ <property name="visible">True</property>
+ <property name="stock">gtk-media-play</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="profile_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Profile</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_profile1_activate" last_modification_time="Thu, 04 Nov 2004 18:51:54 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image84">
+ <property name="visible">True</property>
+ <property name="stock">gtk-justify-left</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="reset_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Reset</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_reset_item_activate" last_modification_time="Fri, 05 Nov 2004 15:34:30 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image85">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Help</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem4_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="about">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_about_activate" last_modification_time="Wed, 31 Dec 2003 20:44:40 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image86">
+ <property name="visible">True</property>
+ <property name="stock">gtk-about</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">3</property>
+ <property name="left_padding">3</property>
+ <property name="right_padding">3</property>
+
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkToolbar" id="toolbar">
+ <property name="visible">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">True</property>
+
+ <child>
+ <widget class="GtkRadioToolButton" id="start_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_tart</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-media-play</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <property name="active">False</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioToolButton" id="profile_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Profile</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-justify-left</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ <property name="active">False</property>
+ <property name="group">start_button</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="reset_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Reset</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-clear</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolItem" id="toolitem1">
+ <property name="visible">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+
+ <child>
+ <widget class="GtkSeparatorToolItem" id="separatortoolitem1">
+ <property name="visible">True</property>
+ <property name="draw">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolButton" id="save_as_button">
+ <property name="visible">True</property>
+ <property name="stock_id">gtk-save-as</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioToolButton" id="dummy_button">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">dummy</property>
+ <property name="use_underline">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+ <property name="active">False</property>
+ <property name="group">start_button</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkToolbar" id="samples-toolbar">
+ <property name="visible">True</property>
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="toolbar_style">GTK_TOOLBAR_BOTH_HORIZ</property>
+ <property name="tooltips">True</property>
+ <property name="show_arrow">False</property>
+
+ <child>
+ <widget class="GtkToolItem" id="toolitem2">
+ <property name="visible">True</property>
+ <property name="visible_horizontal">True</property>
+ <property name="visible_vertical">True</property>
+ <property name="is_important">False</property>
+
+ <child>
+ <widget class="GtkLabel" id="samples_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Samples: 0</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">6</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkHPaned" id="hpaned">
+ <property name="border_width">3</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+
+ <child>
+ <widget class="GtkVPaned" id="vpaned">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="object_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="callers_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="descendants_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
diff --git a/treeviewutils.c b/treeviewutils.c
new file mode 100644
index 0000000..2472eb6
--- /dev/null
+++ b/treeviewutils.c
@@ -0,0 +1,232 @@
+/* -*- mode: C; c-file-style: "linux" -*- */
+
+/* MemProf -- memory profiler and leak detector
+ * Copyright 2002, Soeren Sandmann (sandmann@daimi.au.dk)
+ * Copyright 2003, 2004, Red Hat, Inc.
+ *
+ * Sysprof -- Sampling, systemwide CPU profiler
+ * Copyright 2004, 2005, Soeren Sandmann
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*====*/
+
+#include "treeviewutils.h"
+
+void
+column_set_sort_id (GtkTreeViewColumn *column,
+ int column_id)
+{
+ g_object_set_data (G_OBJECT (column),
+ "mi-saved-sort-column", GINT_TO_POINTER (column_id));
+ gtk_tree_view_column_set_sort_column_id (column, column_id);
+}
+
+void
+tree_view_unset_sort_ids (GtkTreeView *tree_view)
+{
+ GList *columns = gtk_tree_view_get_columns (tree_view);
+ GList *l;
+
+ for (l = columns; l; l = l->next) {
+ gtk_tree_view_column_set_sort_column_id (l->data, -1);
+ }
+
+ g_list_free (columns);
+}
+
+void
+tree_view_set_sort_ids (GtkTreeView *tree_view)
+{
+ GList *columns = gtk_tree_view_get_columns (tree_view);
+ GList *l;
+
+ for (l = columns; l; l = l->next) {
+ int column_id = GPOINTER_TO_INT (g_object_get_data (l->data, "mi-saved-sort-column"));
+ gtk_tree_view_column_set_sort_column_id (l->data, column_id);
+ }
+
+ g_list_free (columns);
+}
+
+int
+list_iter_get_index (GtkTreeModel *model,
+ GtkTreeIter *iter)
+{
+ GtkTreePath *path = gtk_tree_model_get_path (model,iter);
+ int result;
+
+ g_assert (path);
+ g_assert (gtk_tree_path_get_depth (path) == 1);
+ result = gtk_tree_path_get_indices (path)[0];
+ gtk_tree_path_free (path);
+
+ return result;
+
+}
+
+GtkTreeViewColumn *
+add_plain_text_column (GtkTreeView *view, const gchar *title, gint model_column)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ column = gtk_tree_view_column_new_with_attributes (title, renderer,
+ "text", model_column,
+ NULL);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_append_column (view, column);
+ column_set_sort_id (column, model_column);
+
+ return column;
+}
+
+static void
+pointer_to_text (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell, GtkTreeModel *tree_model,
+ GtkTreeIter *iter, gpointer data)
+{
+ gpointer p;
+ gchar *text;
+ int column = GPOINTER_TO_INT (data);
+
+ gtk_tree_model_get (tree_model, iter, column, &p, -1);
+ text = g_strdup_printf ("%p", p);
+ g_object_set (cell, "text", text, NULL);
+ g_free (text);
+}
+
+typedef struct {
+ int column;
+ char *format;
+} ColumnInfo;
+
+static void
+double_to_text (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell, GtkTreeModel *tree_model,
+ GtkTreeIter *iter, gpointer data)
+{
+ gdouble d;
+ gchar *text;
+ ColumnInfo *info = data;
+
+ gtk_tree_model_get (tree_model, iter, info->column, &d, -1);
+
+ text = g_strdup_printf (info->format, d);
+
+ g_object_set (cell, "text", text, NULL);
+ g_free (text);
+}
+
+static void
+free_column_info (void *data)
+{
+ ColumnInfo *info = data;
+ g_free (info->format);
+ g_free (info);
+}
+
+GtkTreeViewColumn *
+add_double_format_column (GtkTreeView *view, const gchar *title, gint model_column, const char *format)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ ColumnInfo *column_info = g_new (ColumnInfo, 1);
+
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "xalign", 1.0, NULL);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, title);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_resizable (column, FALSE);
+
+ column_info->column = model_column;
+ column_info->format = g_strdup (format);
+
+ gtk_tree_view_column_set_cell_data_func (column, renderer,
+ double_to_text, column_info, free_column_info);
+
+ gtk_tree_view_append_column (view, column);
+ column_set_sort_id (column, model_column);
+
+ return column;
+}
+
+GtkTreeViewColumn *
+add_pointer_column (GtkTreeView *view, const gchar *title, gint model_column)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ renderer = gtk_cell_renderer_text_new ();
+
+ column = gtk_tree_view_column_new ();
+ if (title)
+ gtk_tree_view_column_set_title (column, title);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer,
+ pointer_to_text, GINT_TO_POINTER (model_column), NULL);
+
+ gtk_tree_view_append_column (view, column);
+ column_set_sort_id (column, model_column);
+
+ return column;
+}
+
+typedef struct
+{
+ gboolean is_sorted;
+ int sort_column;
+ GtkSortType sort_type;
+} SortState;
+
+
+gpointer
+save_sort_state (GtkTreeView *view)
+{
+ SortState *state = NULL;
+ GtkTreeModel *model = gtk_tree_view_get_model (view);
+
+ if (model && GTK_IS_TREE_SORTABLE (model)) {
+ state = g_new (SortState, 1);
+ state->is_sorted = gtk_tree_sortable_get_sort_column_id (
+ GTK_TREE_SORTABLE (model),
+ &(state->sort_column),
+ &(state->sort_type));
+ }
+ return state;
+}
+
+void
+restore_sort_state (GtkTreeView *view, gpointer st)
+{
+ SortState *state = st;
+ GtkTreeModel *model = gtk_tree_view_get_model (view);
+
+ if (state) {
+ if (state->is_sorted && model && GTK_IS_TREE_SORTABLE (model)) {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+ state->sort_column,
+ state->sort_type);
+ }
+ g_free (state);
+ }
+
+ gtk_tree_sortable_sort_column_changed (GTK_TREE_SORTABLE (model));
+}
diff --git a/treeviewutils.h b/treeviewutils.h
new file mode 100644
index 0000000..908a22c
--- /dev/null
+++ b/treeviewutils.h
@@ -0,0 +1,45 @@
+/* -*- mode: C; c-file-style: "linux" -*- */
+
+/* MemProf -- memory profiler and leak detector
+ * Copyright 2002, Soeren Sandmann (sandmann@daimi.au.dk)
+ * Copyright 2003, 2004, Red Hat, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*====*/
+
+#include <gtk/gtk.h>
+
+void column_set_sort_id (GtkTreeViewColumn *column,
+ int column_id);
+void tree_view_unset_sort_ids (GtkTreeView *tree_view);
+void tree_view_set_sort_ids (GtkTreeView *tree_view);
+
+int list_iter_get_index (GtkTreeModel *model,
+ GtkTreeIter *iter);
+
+GtkTreeViewColumn *add_plain_text_column (GtkTreeView *view,
+ const char *title,
+ gint model_column);
+GtkTreeViewColumn *add_double_format_column (GtkTreeView *view,
+ const char *title,
+ int model_column,
+ const char *format);
+GtkTreeViewColumn *add_pointer_column (GtkTreeView *view,
+ const char *title,
+ int model_column);
+gpointer save_sort_state (GtkTreeView *view);
+void restore_sort_state (GtkTreeView *view,
+ gpointer state);
diff --git a/watch.c b/watch.c
new file mode 100644
index 0000000..b1e4824
--- /dev/null
+++ b/watch.c
@@ -0,0 +1,328 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- */
+
+/* - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <glib.h>
+#include "watch.h"
+
+typedef struct Watch Watch;
+
+struct Watch {
+ GSource source;
+ GPollFD poll_fd;
+ gboolean removed;
+
+ WatchCallback read_callback;
+ WatchCallback write_callback;
+ WatchCallback hangup_callback;
+ WatchCallback error_callback;
+ WatchCallback priority_callback;
+
+ gpointer data;
+};
+
+static GHashTable *watched_fds;
+
+static void
+init (void)
+{
+ if (!watched_fds)
+ watched_fds = g_hash_table_new (g_int_hash, g_int_equal);
+}
+
+static Watch *
+lookup_watch (gint fd)
+{
+ init ();
+
+ return g_hash_table_lookup (watched_fds, &fd);
+}
+
+static void
+internal_add_watch (Watch *watch)
+{
+ gpointer fd = &(watch->poll_fd.fd);
+
+ init ();
+
+ g_hash_table_insert (watched_fds, fd, watch);
+ g_source_add_poll ((GSource *)watch, &(watch->poll_fd));
+}
+
+static void
+internal_remove_watch (Watch *watch)
+{
+ gpointer fd = &(watch->poll_fd.fd);
+
+ init ();
+
+ watch->removed = TRUE;
+ g_source_remove_poll ((GSource *)watch, &(watch->poll_fd));
+ g_hash_table_remove (watched_fds, fd);
+}
+
+static gboolean
+watch_prepare (GSource *source,
+ gint *timeout)
+{
+ *timeout = -1;
+
+ return FALSE;
+}
+
+static gboolean
+watch_check (GSource *source)
+{
+ Watch *watch = (Watch *)source;
+ gint revents = watch->poll_fd.revents;
+
+ if (revents & (G_IO_NVAL))
+ {
+ /* This can happen if the user closes the file descriptor
+ * without first removing the watch. We silently ignore it
+ */
+ internal_remove_watch (watch);
+ g_source_unref (source);
+ return FALSE;
+ }
+
+ if ((revents & G_IO_HUP) && watch->hangup_callback)
+ return TRUE;
+
+ if ((revents & G_IO_IN) && watch->read_callback)
+ return TRUE;
+
+ if ((revents & G_IO_PRI) && watch->priority_callback)
+ return TRUE;
+
+ if ((revents & G_IO_ERR) && watch->error_callback)
+ return TRUE;
+
+ if ((revents & G_IO_OUT) && watch->write_callback)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
+watch_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ Watch *watch = (Watch *)source;
+ gint revents = watch->poll_fd.revents;
+ gboolean removed;
+
+ g_source_ref (source);
+
+ if (!watch->removed && (revents & G_IO_IN) && watch->read_callback)
+ watch->read_callback (watch->data);
+
+ if (!watch->removed && (revents & G_IO_PRI) && watch->priority_callback)
+ watch->priority_callback (watch->data);
+
+ if (!watch->removed && (revents & G_IO_OUT) && watch->write_callback)
+ watch->write_callback (watch->data);
+
+ if (!watch->removed && (revents & G_IO_ERR) && watch->error_callback)
+ watch->error_callback (watch->data);
+
+ if (!watch->removed && (revents & G_IO_HUP) && watch->hangup_callback)
+ watch->hangup_callback (watch->data);
+
+ removed = watch->removed;
+
+ g_source_unref (source);
+
+ if (removed)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+watch_finalize (GSource *source)
+{
+}
+
+static void
+update_poll_mask (Watch *watch)
+{
+ gint events = 0;
+
+ g_source_remove_poll ((GSource *)watch, &(watch->poll_fd));
+
+ if (watch->read_callback)
+ events |= G_IO_IN;
+
+ if (watch->write_callback)
+ events |= G_IO_OUT;
+
+ if (watch->priority_callback)
+ events |= G_IO_PRI;
+
+ if (watch->hangup_callback)
+ events |= G_IO_HUP;
+
+ if (watch->error_callback)
+ events |= G_IO_ERR;
+
+ watch->poll_fd.events = events;
+
+ g_source_add_poll ((GSource *)watch, &(watch->poll_fd));
+}
+
+void
+fd_add_watch (gint fd,
+ gpointer data)
+{
+ static GSourceFuncs watch_funcs = {
+ watch_prepare,
+ watch_check,
+ watch_dispatch,
+ watch_finalize,
+ };
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch == NULL);
+
+ watch = (Watch *)g_source_new (&watch_funcs, sizeof (Watch));
+ g_source_set_can_recurse ((GSource *)watch, TRUE);
+ g_source_attach ((GSource *)watch, NULL);
+
+ watch->poll_fd.fd = fd;
+ watch->poll_fd.events = 0;
+ watch->removed = FALSE;
+
+ watch->read_callback = NULL;
+ watch->write_callback = NULL;
+ watch->hangup_callback = NULL;
+ watch->error_callback = NULL;
+ watch->priority_callback = NULL;
+
+ watch->data = data;
+
+ internal_add_watch (watch);
+}
+
+void
+fd_set_read_callback (gint fd,
+ WatchCallback read_cb)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch != NULL);
+
+ if (watch->read_callback != read_cb)
+ {
+ watch->read_callback = read_cb;
+ update_poll_mask (watch);
+ }
+}
+
+void
+fd_set_write_callback (gint fd,
+ WatchCallback write_cb)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch != NULL);
+
+ if (watch->write_callback != write_cb)
+ {
+ watch->write_callback = write_cb;
+ update_poll_mask (watch);
+ }
+}
+
+void
+fd_set_hangup_callback (gint fd,
+ WatchCallback hangup_cb)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch != NULL);
+
+ if (watch->hangup_callback != hangup_cb)
+ {
+ watch->hangup_callback = hangup_cb;
+ update_poll_mask (watch);
+ }
+}
+
+void
+fd_set_error_callback (gint fd,
+ WatchCallback error_cb)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch != NULL);
+
+ if (watch->error_callback != error_cb)
+ {
+ watch->error_callback = error_cb;
+ update_poll_mask (watch);
+ }
+}
+
+void
+fd_set_priority_callback (gint fd,
+ WatchCallback priority_cb)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+ g_return_if_fail (watch != NULL);
+
+ if (watch->priority_callback != priority_cb)
+ {
+ watch->priority_callback = priority_cb;
+ update_poll_mask (watch);
+ }
+}
+
+void
+fd_remove_watch (gint fd)
+{
+ Watch *watch = lookup_watch (fd);
+
+ g_return_if_fail (fd > 0);
+
+ if (!watch)
+ return;
+
+ internal_remove_watch (watch);
+ g_source_unref ((GSource *)watch);
+}
+
+gboolean
+fd_is_watched (gint fd)
+{
+ g_return_val_if_fail (fd > 0, FALSE);
+
+ if (lookup_watch (fd))
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/watch.h b/watch.h
new file mode 100644
index 0000000..78bac2d
--- /dev/null
+++ b/watch.h
@@ -0,0 +1,40 @@
+/* - Library for asynchronous communication
+ * Copyright (C) 2002 Søren Sandmann (sandmann@daimi.au.dk)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <glib.h>
+
+/*
+ * Watching file descriptors
+ */
+typedef void (* WatchCallback) (gpointer data);
+
+void fd_add_watch (gint fd,
+ gpointer data);
+void fd_set_read_callback (gint fd,
+ WatchCallback read_cb);
+void fd_set_write_callback (gint fd,
+ WatchCallback write_cb);
+void fd_set_hangup_callback (gint fd,
+ WatchCallback hangup_cb);
+void fd_set_error_callback (gint fd,
+ WatchCallback error_cb);
+void fd_set_priority_callback (gint fd,
+ WatchCallback priority_cb);
+void fd_remove_watch (gint fd);
+gboolean fd_is_watched (gint fd);
+