pax_global_header00006660000000000000000000000064146211042460014512gustar00rootroot0000000000000052 comment=ca7c1e03367f5a9f532a25d5c39eaadb81048ad6 headache-1.08/000077500000000000000000000000001462110424600131645ustar00rootroot00000000000000headache-1.08/.gitignore000066400000000000000000000000661462110424600151560ustar00rootroot00000000000000_build .merlin headache.install .vscode/settings.json headache-1.08/LICENSE000066400000000000000000000614441462110424600142020ustar00rootroot00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 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. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library 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 Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! headache-1.08/Makefile000066400000000000000000000035501462110424600146270ustar00rootroot00000000000000########################################################################## # # # Headache # # # # Vincent Simonet, Projet Cristal, INRIA Rocquencourt # # # # Copyright 2002 # # Institut National de Recherche en Informatique et en Automatique. # # All rights reserved. This file is distributed under the terms of # # the GNU Library General Public License. # # # # Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ # # # ########################################################################## .PHONY: headache clean install test headache: dune build clean:: dune clean # install install: ifndef INSTALLDIR $(error "Please define INSTALLDIR.") else mkdir -p $(INSTALLDIR) cp -f _build/install/default/bin/headache $(INSTALLDIR)/headache endif # test bootstrap: headache dune exec -- headache -h example $(filter-out config_builtin.ml, $(wildcard *.ml*)) Makefile doc-src/Makefile doc-src/manual.tex test: bootstrap dune exec -- headache -e Makefile > example.txt diff -q example example.txt rm -f example.txt # documentation ifndef DOC_INSTALLDIR DOC_SRC= doc-src # default installation from ./doc-src to ./doc and update of ./README DOC_INSTALLDIR= doc .PHONY: install-doc install-doc:: cp -f doc-src/manual.txt ./README else # for installation from ./doc to $(DOC_INSTALLDIR) DOC_SRC= doc endif sinclude doc-src/Makefile headache-1.08/README000066400000000000000000000230101462110424600140400ustar00rootroot00000000000000 `headache` ********** Vincent Simonet =============== November, 2002 ============== This manual is also available in plain text (1), PostScript (2) and PDF (3). 1 Overview *=*=*=*=*= It is a common usage to put at the beginning of source code files a short header giving, for instance, some copyright informations. `headache` is a simple and lightweight tool for managing easily these headers. Among its functionalities, one may mention: - Headers must generally be generated as comments in source code files. `headache` deals with different file types and generates for each of them headers in an appropriate format. - `headache` automatically detects existing headers and removes them. Thus, you can use it to update headers in a set of files. `headache` is distributed under the terms of the GNU Library General Public License. See file `LICENSE` of the distribution for more information. 2 Compilation and installation *=*=*=*=*=*=*=*=*=*=*=*=*=*=*= Building `headache` requires Objective Caml (available at http://caml.inria.fr/) and GNU Make. In addition, from version 1.03-utf8, the build requires the Unicode library Camomile and, from version 1.04, Dune. Instructions `headache` is available through OPAM (available at http://opam.ocaml.org/), the OCaml Package Manager. This is the preferred installation method. Then the following sequence of commands should install the package: << opam init opam install headache >> Alternatively, you can use these commands (Dune must be installed): << make && sudo make INSTALLDIR=/usr/local/bin install >> Build the executable and install it into the specified directory. 3 Usage *=*=*=* Let us illustrate the use of this tool with a small example. Assume you have a small project mixing C and Caml code consisting in three files `foo.c`, `bar.ml` and `bar.mli`, and you want to equip them with some header. First of all, write a header file, i.e. a plain text file including the information headers must mention. An example of such a file is given in figure 1. In the following, we assume this file is named `myheader` and is in the same directory as source files. Then, in order to generate headers, just run the command: << headache -h myheader foo.c bar.ml bar.mli >> Each file is equipped with a header including the text given in the header file `myheader`, surrounded by some extra characters depending on its format making it a comment (e.g. `(*` and `*)` in `.ml` files). If you update informations in the header file `myheader`, you simply need to re-run the above command to update headers in source code files: existing ones are automatically removed. Similarly, running: << headache -r foo.c bar.ml bar.mli >> removes any existing in files `foo.c`, `bar.ml` and `bar.mli`. Files which do not have a header are kept unchanged. The current headers of files can be extracted: << headache -e foo.c bar.ml bar.mli >> prints on the standard output the current headers of the files `foo.c`, `bar.ml` and `bar.mli`. All files are kept unchanged. -------------------------------------------------------------------- << Headache Automatic generation of files headers Vincent Simonet, Projet Cristal, INRIA Rocquencourt Copyright 2002 Institut National de Recherche en Informatique et en Automatique. All rights reserved. This file is distributed under the terms of the GNU Library General Public License. Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ >> Figure 1: An example of header file -------------------------------------------------------------------- 4 Configuration file *=*=*=*=*=*=*=*=*=*= File types and format of header may be specified by a configuration file. By default, the default builtin configuration file given in figure 2 is used. You can also use your own configuration file thanks to the `-c` option: << headache -c myconfig -h myheader foo.c bar.ml bar.mli >> In order to write your own configuration, you can follow the example given in figure 2. A configuration file consists in a list of entries separated by the character `|`. Each of them is made of two parts separated by an `->`: - The first one is a regular expression. Regular expression are enclosed within double quotes and have the same syntax as in Gnu Emacs. `headache` determines file types according to file basenames; thus, each file is dealt with using the first line its name matches. - The second one describes the format of headers for files of this type. It consists of the name of a model (e.g. `frame`), possibly followed by a list of arguments. Arguments are named: `open:"(*"` means that the value of the argument `open` is `(*`. `headache` currently supports three models: - `frame`. With this model, headers are generated in a frame. This model requires three arguments: `open` and `close` (the opening and closing sequences for comments) and `line` (the character used to make the horizontal lines of the frame). Two optional arguments may be used: `margin` (a string printed between the left and right side of the frame and the border, by default two spaces) and `width` (the width of the inside of the frame, default is 68). - `lines`. Headers are typeset between two lines. Three arguments must be provided: `open` and `close` (the opening and closing sequences for comments), `line` (the character used to make the horizontal lines). Three optional arguments are allowed: `begin` (a string typeset at the beginning of each line, by default two spaces), `last` (a string typeset at the beginning of the last line) and `width` (the width of the lines, default is 70). - `no`. This model generates no header and has no argument. It is possible to change the default builtin configuration file at compile time. For this, just edit the file `config_builtin.txt` present in the source distribution before building the software. -------------------------------------------------------------------- << # Objective Caml source ".*\\.ml[il]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.fml[i]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.mly" -> frame open:"/*" line:"*" close:"*/" # C source | ".*\\.[chy]" -> frame open:"/*" line:"*" close:"*/" # Latex | ".*\\.tex" -> frame open:"%" line:"%" close:"%" # Misc | ".*Makefile.*" -> frame open:"#" line:"#" close:"#" | ".*README.*" -> frame open:"*" line:"*" close:"*" | ".*LICENSE.*" -> frame open:"*" line:"*" close:"*" >> Figure 2: The default builtin configuration file -------------------------------------------------------------------- It is also possible to add entries into your own configuration file that specify when the initial lines of the processed file have to be skipped. As previously, these entries are separated by the character `|` and each of them is made of two parts separated by an `->`: - Again, the first part is a regular expression used by `headache` to determine the file type. But here, it is according to its full filename (including the pathname). - The second part specifies when the initial lines must be skipped. It consists of the keyword `skip` followed by one of the named arguments `multiline_match:` or `match:`, then a regular expression. As long as the lines match a `multiline_match` parameter, `headache` skips them and checks the next line. If the current line matches only a `match` parameter, `headache` skips the current line and breaks the iteration there (of course, if nothing matches, `headache` puts the header before the current line). -------------------------------------------------------------------- <<# Script file | ".*\\.sh" -> frame open:"#" line:"#" close:"#" | ".*\\.sh" -> skip match:"#!.*" >> Figure 3: Example of a configuration file for skipping the shebang line of shell scripts -------------------------------------------------------------------- Figure 3 shows an example of configuration file that can used to skip the shebang line of shell scripts: when the first line of `.sh` files starts with `#!`, `headache` does not modify that line and considers that the header must start at the second line. -------------------------------------------------------------------- <<# SWI Prolog file | ".*\\.pl" -> frame open:"%" line:"%" close:"%" | ".*\\.pl" -> skip multiline_match:"#!.*" multiline_match:":-.*" >> Figure 4: Example of a configuration file for skipping the shebang line, as well as lines containing Prolog directives, such as Unicode usage. -------------------------------------------------------------------- Figure 4 shows an example of configuration file that can used for `SWI prolog` files: for a `.pl` file starting with the following three first lines, `headache` considers that the header must start just after the first two lines: << #!/usr/bin/env swipl :- encoding(utf8). % remainder of the file, that can be after the header >> ----------------------------------------------------------------------- This document was translated from LaTeX by HeVeA (4). ----------------------------------- (1) manual.txt (2) manual.ps.gz (3) manual.pdf (4) http://hevea.inria.fr/index.html headache-1.08/config.ml000066400000000000000000000021351462110424600147640ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) exception Error of string * int * int headache-1.08/config_builtin.txt000066400000000000000000000010151462110424600167150ustar00rootroot00000000000000# Builtin configuration file # Objective Caml source ".*\\.ml[il]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.fml[i]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.mly" -> frame open:"/*" line:"*" close:"*/" # C source | ".*\\.[chy]" -> frame open:"/*" line:"*" close:"*/" # Latex | ".*\\.tex" -> frame open:"%" line:"%" close:"%" # Misc | ".*Makefile.*" -> frame open:"#" line:"#" close:"#" | ".*README.*" -> frame open:"*" line:"*" close:"*" | ".*LICENSE.*" -> frame open:"*" line:"*" close:"*" headache-1.08/config_lex.mll000066400000000000000000000102341462110424600160070ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) { open Printf open Config_parse (* To buffer string literals *) let initial_string_buffer = Bytes.create 256 let string_buff = ref initial_string_buffer let string_index = ref 0 let reset_string_buffer () = string_buff := initial_string_buffer; string_index := 0 let store_string_char c = let len = Bytes.length (!string_buff) in if !string_index >= len then begin let new_buff = Bytes.create (len * 2) in Bytes.blit (!string_buff) 0 new_buff 0 len; string_buff := new_buff end; Bytes.set (!string_buff) (!string_index) c; incr string_index let get_stored_string () = let s = Bytes.sub (!string_buff) 0 (!string_index) in string_buff := initial_string_buffer; s (* To translate escape sequences *) let char_for_backslash = match Sys.os_type with | "Unix" | "Win32" | "Cygwin" -> begin function | 'n' -> '\010' | 'r' -> '\013' | 'b' -> '\008' | 't' -> '\009' | c -> c end | "MacOS" -> begin function | 'n' -> '\013' | 'r' -> '\010' | 'b' -> '\008' | 't' -> '\009' | c -> c end | _ -> (* TEMPORARY Error "Unknown system type" *) assert false let char_for_decimal_code lexbuf i = let c = 100 * (Char.code(Lexing.lexeme_char lexbuf i) - 48) + 10 * (Char.code(Lexing.lexeme_char lexbuf (i+1)) - 48) + (Char.code(Lexing.lexeme_char lexbuf (i+2)) - 48) in if c < 0 || c > 255 then raise (Config.Error(sprintf "illegal escape %s" (Lexing.lexeme lexbuf), Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) else Char.chr c (* To store the position of the beginning of a string *) let string_start_pos = ref 0 } let blank = [' ' '\010' '\013' '\009' '\012'] let identchar = ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9'] rule token = parse blank + { token lexbuf } | "->" { ARROW } | "|" { PIPE } | ":" { COLON } | "#" [^ '\010' '\013']* ['\010' '\013'] { token lexbuf } | identchar+ { STRING (Lexing.lexeme lexbuf) } | "\"" { reset_string_buffer(); let string_start = Lexing.lexeme_start lexbuf in string_start_pos := string_start; string lexbuf; lexbuf.Lexing.lex_start_pos <- string_start - lexbuf.Lexing.lex_abs_pos; STRING (Bytes.to_string (get_stored_string())) } | eof { EOF } | _ { raise (Config.Error (sprintf "Illegal character %c" ((Lexing.lexeme lexbuf).[0]), Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) } and string = parse '"' { () } | '\\' ("\010" | "\013" | "\013\010") [' ' '\009'] * { string lexbuf } | '\\' ['\\' '"' 'n' 't' 'b' 'r'] { store_string_char(char_for_backslash(Lexing.lexeme_char lexbuf 1)); string lexbuf } | '\\' ['0'-'9'] ['0'-'9'] ['0'-'9'] { store_string_char(char_for_decimal_code lexbuf 1); string lexbuf } | eof { raise (Config.Error ("Unterminated string", !string_start_pos, !string_start_pos+1)) } | _ { store_string_char(Lexing.lexeme_char lexbuf 0); string lexbuf } headache-1.08/config_parse.mly000066400000000000000000000110471462110424600163510ustar00rootroot00000000000000/**************************************************************************/ /* */ /* Headache */ /* */ /* Vincent Simonet, Projet Cristal, INRIA Rocquencourt */ /* */ /* Copyright 2002 */ /* Institut National de Recherche en Informatique et en Automatique. */ /* All rights reserved. This file is distributed under the terms of */ /* the GNU Library General Public License. */ /* */ /* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ */ /* */ /**************************************************************************/ %{ open Printf type entry = | EntryModel of Model.generator | EntrySkip of Skip.param_skip list ;; (* Dispatch entry considering if it is a skip or a model. * List returned are reversed considering their initial order. *) let rec dispatch_entry acc_model acc_skip lst = match lst with | (rg_filename, EntryModel mdl) :: tl -> dispatch_entry ((rg_filename, mdl) :: acc_model) acc_skip tl | (rg_filename, EntrySkip rg_skip_lst) :: tl -> let nacc_skip = List.fold_left (fun nacc_skip rg_skip -> (rg_filename, rg_skip) :: nacc_skip) acc_skip rg_skip_lst in dispatch_entry acc_model nacc_skip tl | [] -> acc_model, acc_skip %} %token ARROW %token COLON %token EOF %token PIPE %token STRING %start configfile %type <((Str.regexp * Model.generator) list) * ((Str.regexp * Skip.param_skip) list)> configfile %start boot %type <(string * string * (string * string) list) list> boot %% configfile: opt_pipe item_list EOF { dispatch_entry [] [] $2 } ; opt_pipe: /*empty*/ { () } | PIPE { () } ; item_list: item { $1 :: [] } | item_list PIPE item { $3 :: $1 } ; item: STRING ARROW STRING parameters { let regexp = try Str.regexp ("^" ^ $1 ^ "$") with Failure msg -> raise (Config.Error (sprintf "Illegal regexp: %s" msg, Parsing.rhs_start 1, Parsing.rhs_end 1)) in if $3 = "skip" then let fun_parameters (id, str) = if id = "match" then try false,Str.regexp ("^" ^ str ^ "$") with Failure msg -> raise (Config.Error (sprintf "Illegal regexp: %s" msg, Parsing.rhs_start 1, Parsing.rhs_end 1)) else if id = "multiline_match" then try true,(Str.regexp ("^" ^ str ^ "$")) with Failure msg -> raise (Config.Error (sprintf "Illegal regexp: %s" msg, Parsing.rhs_start 1, Parsing.rhs_end 1)) else raise (Config.Error (sprintf "Unkown option '%s' for skip" id, Parsing.rhs_start 3, Parsing.rhs_end 3)) in let skip_lst = List.map fun_parameters (List.rev $4) in regexp, (EntrySkip skip_lst) else let model = try Model.find $3 with Not_found -> raise (Config.Error (sprintf "Unknown model: %s" $3, Parsing.rhs_start 3, Parsing.rhs_end 3)) in let generator = try model (List.rev $4) with Model.Error msg -> raise (Config.Error (msg, Parsing.rhs_start 3, Parsing.rhs_end 4)) in regexp, (EntryModel generator) } ; parameters: /*empty*/ { [] } | parameters STRING COLON STRING { ($2, $4) :: $1 } ; /***************************************************************************/ boot: opt_pipe boot_item_list EOF { List.rev $2 } ; boot_item_list: boot_item { $1 :: [] } | boot_item_list PIPE boot_item { $3 :: $1 } ; boot_item: STRING ARROW STRING parameters { $1, $3, $4 } ; headache-1.08/doc-src/000077500000000000000000000000001462110424600145165ustar00rootroot00000000000000headache-1.08/doc-src/.gitignore000066400000000000000000000001741462110424600165100ustar00rootroot00000000000000/manual.aux /manual.dvi /manual.haux /manual.html /manual.htoc /manual.log /manual.pdf /manual.ps /manual.ps.gz /manual.txt headache-1.08/doc-src/Makefile000066400000000000000000000034741462110424600161660ustar00rootroot00000000000000########################################################################## # # # Headache # # # # Vincent Simonet, Projet Cristal, INRIA Rocquencourt # # # # Copyright 2002 # # Institut National de Recherche en Informatique et en Automatique. # # All rights reserved. This file is distributed under the terms of # # the GNU Library General Public License. # # # # Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ # # # ########################################################################## DOC_SRC?= . MANUAL := $(DOC_SRC)/manual DOC_FILES= $(addprefix $(MANUAL)., pdf ps.gz html txt) .PHONY: doc clean-doc install-doc doc: $(DOC_FILES) clean-doc: rm -f $(addprefix $(MANUAL)., pdf ps ps.gz dvi aux log thm txt html haux htoc) clean:: clean-doc $(MANUAL).dvi: $(MANUAL).tex cd $(dir $@) && latex $(notdir $<) cd $(dir $@) && latex $(notdir $<) $(MANUAL).ps: $(MANUAL).dvi dvips -t a4 -o $@ $< $(MANUAL).ps.gz: $(MANUAL).ps gzip -c $< > $@ $(MANUAL).pdf: $(MANUAL).dvi dvipdfm -p a4 -o $@ $< $(MANUAL).html: $(MANUAL).tex $(MANUAL).dvi hevea -o $@ $< $(MANUAL).txt: $(MANUAL).tex $(MANUAL).dvi hevea -o $@ -text $< install-doc:: ifndef DOC_INSTALLDIR $(error "Please define DOC_INSTALLDIR.") else mkdir -p $(DOC_INSTALLDIR)/ cp -f $(DOC_FILES) $(DOC_INSTALLDIR)/ endif headache-1.08/doc-src/manual.tex000066400000000000000000000272471462110424600165310ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Headache % % % % Vincent Simonet, Projet Cristal, INRIA Rocquencourt % % % % Copyright 2002 % % Institut National de Recherche en Informatique et en Automatique. % % All rights reserved. This file is distributed under the terms of % % the GNU Library General Public License. % % % % Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %BEGIN LATEX \documentclass{article} \setlength{\textheight}{240mm} \setlength{\textwidth}{160mm} \setlength{\topmargin}{-22mm} \setlength{\headheight}{5mm} \setlength{\headsep}{12mm} \setlength{\footskip}{16mm} \setlength{\oddsidemargin}{2.2mm} \setlength{\evensidemargin}{2.2mm} %END LATEX %HEVEA \documentclass{article} \usepackage{alltt} \usepackage{moreverb} \usepackage{url} %BEGIN LATEX \newcommand{\mytt}[1]{\texttt{#1}} %END LATEX %HEVEA \newcommand{\mytt}[1]{`\texttt{#1}`} \newcommand{\headache}{\mytt{headache}} \title{\headache{}} \author{Vincent Simonet} \date{November, 2002} \begin{document} \maketitle %HEVEA This manual is also available in \ahref{manual.txt}{plain text}, %HEVEA \ahref{manual.ps.gz}{PostScript} and \ahref{manual.pdf}{PDF}. % ************************************************************************* \section{Overview} It is a common usage to put at the beginning of source code files a short header giving, for instance, some copyright informations. \headache{} is a simple and lightweight tool for managing easily these headers. Among its functionalities, one may mention: \begin{itemize} \item Headers must generally be generated as \emph{comments} in source code files. \headache{} deals with different file types and generates for each of them headers in an appropriate format. \item \headache{} automatically detects existing headers and removes them. Thus, you can use it to update headers in a set of files. \end{itemize} \headache{} is distributed under the terms of the \emph{GNU Library General Public License}. See file \mytt{LICENSE} of the distribution for more information. % ************************************************************************* \section{Compilation and installation} Building \headache{} requires \emph{Objective Caml} (available at \url{http://caml.inria.fr/}) and \emph{GNU Make}. In addition, from version \texttt{1.03-utf8}, the build requires the Unicode library \emph{Camomile} and, from version \texttt{1.04}, \emph{Dune}. \paragraph{Instructions} \headache{} is available through \emph{OPAM} (available at \url{http://opam.ocaml.org/}), the \emph{OCaml Package Manager}. This is the preferred installation method. Then the following sequence of commands should install the package: \begin{alltt} opam init opam install headache \end{alltt} Alternatively, you can use these commands (\emph{Dune} must be installed): \begin{alltt} make && sudo make INSTALLDIR=/usr/local/bin install \end{alltt} Build the executable and install it into the specified directory. % ************************************************************************* \section{Usage} Let us illustrate the use of this tool with a small example. Assume you have a small project mixing C and Caml code consisting in three files \mytt{foo.c}, \mytt{bar.ml} and \mytt{bar.mli}, and you want to equip them with some header. First of all, write a \emph{header file}, i.e.\ a plain text file including the information headers must mention. An example of such a file is given in figure~\ref{figure:header}. In the following, we assume this file is named \mytt{myheader} and is in the same directory as source files. Then, in order to generate headers, just run the command: \begin{alltt} headache -h myheader foo.c bar.ml bar.mli \end{alltt} Each file is equipped with a header including the text given in the header file \mytt{myheader}, surrounded by some extra characters depending on its format making it a comment (e.g.\ \mytt{(*} and \mytt{*)} in \mytt{.ml} files). If you update informations in the header file \mytt{myheader}, you simply need to re-run the above command to update headers in source code files: existing ones are automatically removed. Similarly, running: \begin{alltt} headache -r foo.c bar.ml bar.mli \end{alltt} removes any existing in files \mytt{foo.c}, \mytt{bar.ml} and \mytt{bar.mli}. Files which do not have a header are kept unchanged. The current headers of files can be extracted: \begin{alltt} headache -e foo.c bar.ml bar.mli \end{alltt} prints on the standard output the current headers of the files \mytt{foo.c}, \mytt{bar.ml} and \mytt{bar.mli}. All files are kept unchanged. \begin{figure} %BEGIN LATEX \begin{center} %END LATEX \begin{boxedverbatim} Headache Automatic generation of files headers Vincent Simonet, Projet Cristal, INRIA Rocquencourt Copyright 2002 Institut National de Recherche en Informatique et en Automatique. All rights reserved. This file is distributed under the terms of the GNU Library General Public License. Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ \end{boxedverbatim} %BEGIN LATEX \end{center} %END LATEX \caption{An example of header file} \label{figure:header} \end{figure} % ************************************************************************* \section{Configuration file} File types and format of header may be specified by a \emph{configuration file}. By default, the default builtin configuration file given in figure~\ref{figure:config} is used. You can also use your own configuration file thanks to the \mytt{-c} option: \begin{alltt} headache -c myconfig -h myheader foo.c bar.ml bar.mli \end{alltt} In order to write your own configuration, you can follow the example given in figure~\ref{figure:config}. A configuration file consists in a list of \emph{entries} separated by the character \mytt{|}. Each of them is made of two parts separated by an \mytt{->}: \begin{itemize} \item The first one is a \emph{regular expression}. Regular expression are enclosed within double quotes and have the same syntax as in Gnu Emacs. \headache{} determines file types according to file basenames; thus, each file is dealt with using the first line its name matches. \item The second one describes the format of headers for files of this type. It consists of the name of a \emph{model} (e.g.\ \mytt{frame}), possibly followed by a list of arguments. Arguments are named: \mytt{open:"(*"} means that the value of the argument \mytt{open} is \mytt{(*}. \end{itemize} \headache{} currently supports three \emph{models}: \begin{itemize} \item \mytt{frame}. With this model, headers are generated in a frame. This model requires three arguments: \mytt{open} and \mytt{close} (the opening and closing sequences for comments) and \mytt{line} (the character used to make the horizontal lines of the frame). Two optional arguments may be used: \mytt{margin} (a string printed between the left and right side of the frame and the border, by default two spaces) and \mytt{width} (the width of the inside of the frame, default is 68). \item \mytt{lines}. Headers are typeset between two lines. Three arguments must be provided: \mytt{open} and \mytt{close} (the opening and closing sequences for comments), \mytt{line} (the character used to make the horizontal lines). Three optional arguments are allowed: \mytt{begin} (a string typeset at the beginning of each line, by default two spaces), \mytt{last} (a string typeset at the beginning of the last line) and \mytt{width} (the width of the lines, default is 70). \item \mytt{no}. This model generates no header and has no argument. \end{itemize} It is possible to change the default builtin configuration file at compile time. For this, just edit the file \mytt{config\_builtin.txt} present in the source distribution before building the software. \begin{figure} %BEGIN LATEX \begin{center} %END LATEX \begin{boxedverbatim} # Objective Caml source ".*\\.ml[il]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.fml[i]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.mly" -> frame open:"/*" line:"*" close:"*/" # C source | ".*\\.[chy]" -> frame open:"/*" line:"*" close:"*/" # Latex | ".*\\.tex" -> frame open:"%" line:"%" close:"%" # Misc | ".*Makefile.*" -> frame open:"#" line:"#" close:"#" | ".*README.*" -> frame open:"*" line:"*" close:"*" | ".*LICENSE.*" -> frame open:"*" line:"*" close:"*" \end{boxedverbatim} %BEGIN LATEX \end{center} %END LATEX \caption{The default builtin configuration file} \label{figure:config} \end{figure} It is also possible to add entries into your own configuration file that specify when the initial lines of the processed file have to be skipped. As previously, these \emph{entries} are separated by the character \mytt{|} and each of them is made of two parts separated by an \mytt{->}: \begin{itemize} \item Again, the first part is a \emph{regular expression} used by \headache{} to determine the file type. But here, it is according to its full filename (including the pathname). \item The second part specifies when the initial lines must be skipped. It consists of the keyword \mytt{skip} followed by one of the named arguments \mytt{multiline\_match:} or \mytt{match:}, then a \emph{regular expression}. As long as the lines match a \mytt{multiline\_match} parameter, \headache{} skips them and checks the next line. If the current line matches only a \mytt{match} parameter, \headache{} skips the current line and breaks the iteration there (of course, if nothing matches, \headache{} puts the header before the current line). \end{itemize} \begin{figure} %BEGIN LATEX \begin{center} %END LATEX \begin{boxedverbatim} # Script file | ".*\\.sh" -> frame open:"#" line:"#" close:"#" | ".*\\.sh" -> skip match:"#!.*" \end{boxedverbatim} %BEGIN LATEX \end{center} %END LATEX \caption{Example of a configuration file for skipping the shebang line of shell scripts} \label{figure:example} \end{figure} Figure~\ref{figure:example} shows an example of configuration file that can used to skip the shebang line of shell scripts: when the first line of \mytt{.sh} files starts with \mytt{\#!}, \headache{} does not modify that line and considers that the header must start at the second line. \begin{figure} %BEGIN LATEX \begin{center} %END LATEX \begin{boxedverbatim} # SWI Prolog file | ".*\\.pl" -> frame open:"%" line:"%" close:"%" | ".*\\.pl" -> skip multiline_match:"#!.*" multiline_match:":-.*" \end{boxedverbatim} %BEGIN LATEX \end{center} %END LATEX \caption{Example of a configuration file for skipping the shebang line, as well as lines containing Prolog directives, such as Unicode usage.} \label{figure:python-example} \end{figure} Figure~\ref{figure:python-example} shows an example of configuration file that can used for \mytt{SWI prolog} files: for a \mytt{.pl} file starting with the following three first lines, \headache{} considers that the header must start just after the first two lines: \begin{alltt} #!/usr/bin/env swipl :- encoding(utf8). % remainder of the file, that can be after the header \end{alltt} \end{document} %%% Local Variables: %%% mode: latex %%% TeX-master: t %%% End: headache-1.08/doc/000077500000000000000000000000001462110424600137315ustar00rootroot00000000000000headache-1.08/doc/manual.html000066400000000000000000000463511462110424600161050ustar00rootroot00000000000000 `headache`

headache

Vincent Simonet

November, 2002

This manual is also available in plain text, PostScript and PDF.

1 Overview

It is a common usage to put at the beginning of source code files a short header giving, for instance, some copyright informations. ‘headache‘ is a simple and lightweight tool for managing easily these headers. Among its functionalities, one may mention:

  • Headers must generally be generated as comments in source code files. ‘headache‘ deals with different file types and generates for each of them headers in an appropriate format.
  • headache‘ automatically detects existing headers and removes them. Thus, you can use it to update headers in a set of files.

headache‘ is distributed under the terms of the GNU Library General Public License. See file ‘LICENSE‘ of the distribution for more information.

2 Compilation and installation

Building ‘headache‘ requires Objective Caml (available at http://caml.inria.fr/) and GNU Make. In addition, from version 1.03-utf8, the build requires the Unicode library Camomile and, from version 1.04, Dune.

Instructions

headache‘ is available through OPAM (available at http://opam.ocaml.org/), the OCaml Package Manager. This is the preferred installation method. Then the following sequence of commands should install the package:

  opam init
  opam install headache

Alternatively, you can use these commands (Dune must be installed):

  make && sudo make INSTALLDIR=/usr/local/bin install

Build the executable and install it into the specified directory.

3 Usage

Let us illustrate the use of this tool with a small example. Assume you have a small project mixing C and Caml code consisting in three files ‘foo.c‘, ‘bar.ml‘ and ‘bar.mli‘, and you want to equip them with some header. First of all, write a header file, i.e. a plain text file including the information headers must mention. An example of such a file is given in figure 1. In the following, we assume this file is named ‘myheader‘ and is in the same directory as source files.

Then, in order to generate headers, just run the command:

  headache -h myheader foo.c bar.ml bar.mli

Each file is equipped with a header including the text given in the header file ‘myheader‘, surrounded by some extra characters depending on its format making it a comment (e.g. ‘(*‘ and ‘*)‘ in ‘.ml‘ files). If you update informations in the header file ‘myheader‘, you simply need to re-run the above command to update headers in source code files: existing ones are automatically removed.

Similarly, running:

  headache -r foo.c bar.ml bar.mli

removes any existing in files ‘foo.c‘, ‘bar.ml‘ and ‘bar.mli‘. Files which do not have a header are kept unchanged.

The current headers of files can be extracted:

  headache -e foo.c bar.ml bar.mli

prints on the standard output the current headers of the files ‘foo.c‘, ‘bar.ml‘ and ‘bar.mli‘. All files are kept unchanged.


                             Headache
               Automatic generation of files headers

        Vincent Simonet, Projet Cristal, INRIA Rocquencourt

Copyright 2002
Institut National de Recherche en Informatique et en Automatique.
All rights reserved.  This file is distributed under the terms of
the GNU Library General Public License.

Vincent.Simonet@inria.fr           http://cristal.inria.fr/~simonet/
Figure 1: An example of header file

4 Configuration file

File types and format of header may be specified by a configuration file. By default, the default builtin configuration file given in figure 2 is used. You can also use your own configuration file thanks to the ‘-c‘ option:

  headache -c myconfig -h myheader foo.c bar.ml bar.mli

In order to write your own configuration, you can follow the example given in figure 2. A configuration file consists in a list of entries separated by the character ‘|‘. Each of them is made of two parts separated by an ‘->‘:

  • The first one is a regular expression. Regular expression are enclosed within double quotes and have the same syntax as in Gnu Emacs. ‘headache‘ determines file types according to file basenames; thus, each file is dealt with using the first line its name matches.
  • The second one describes the format of headers for files of this type. It consists of the name of a model (e.g. ‘frame‘), possibly followed by a list of arguments. Arguments are named: ‘open:"(*"‘ means that the value of the argument ‘open‘ is ‘(*‘.

headache‘ currently supports three models:

  • frame‘. With this model, headers are generated in a frame. This model requires three arguments: ‘open‘ and ‘close‘ (the opening and closing sequences for comments) and ‘line‘ (the character used to make the horizontal lines of the frame). Two optional arguments may be used: ‘margin‘ (a string printed between the left and right side of the frame and the border, by default two spaces) and ‘width‘ (the width of the inside of the frame, default is 68).
  • lines‘. Headers are typeset between two lines. Three arguments must be provided: ‘open‘ and ‘close‘ (the opening and closing sequences for comments), ‘line‘ (the character used to make the horizontal lines). Three optional arguments are allowed: ‘begin‘ (a string typeset at the beginning of each line, by default two spaces), ‘last‘ (a string typeset at the beginning of the last line) and ‘width‘ (the width of the lines, default is 70).
  • no‘. This model generates no header and has no argument.

It is possible to change the default builtin configuration file at compile time. For this, just edit the file ‘config_builtin.txt‘ present in the source distribution before building the software.


# Objective Caml source
  ".*\\.ml[il]?" -> frame open:"(*" line:"*" close:"*)"
| ".*\\.fml[i]?" -> frame open:"(*" line:"*" close:"*)"
| ".*\\.mly"     -> frame open:"/*" line:"*" close:"*/"
# C source
| ".*\\.[chy]"    -> frame open:"/*" line:"*" close:"*/"
# Latex
| ".*\\.tex"     -> frame open:"%"  line:"%" close:"%"
# Misc
| ".*Makefile.*" -> frame open:"#"  line:"#" close:"#"
| ".*README.*"   -> frame open:"*"  line:"*" close:"*"
| ".*LICENSE.*"  -> frame open:"*"  line:"*" close:"*"
Figure 2: The default builtin configuration file

It is also possible to add entries into your own configuration file that specify when the initial lines of the processed file have to be skipped. As previously, these entries are separated by the character ‘|‘ and each of them is made of two parts separated by an ‘->‘:

  • Again, the first part is a regular expression used by ‘headache‘ to determine the file type. But here, it is according to its full filename (including the pathname).
  • The second part specifies when the initial lines must be skipped. It consists of the keyword ‘skip‘ followed by one of the named arguments ‘multiline_match:‘ or ‘match:‘, then a regular expression. As long as the lines match a ‘multiline_match‘ parameter, ‘headache‘ skips them and checks the next line. If the current line matches only a ‘match‘ parameter, ‘headache‘ skips the current line and breaks the iteration there (of course, if nothing matches, ‘headache‘ puts the header before the current line).

# Script file
 | ".*\\.sh" -> frame open:"#"  line:"#" close:"#"
 | ".*\\.sh" -> skip match:"#!.*"
Figure 3: Example of a configuration file for skipping the shebang line of shell scripts

Figure 3 shows an example of configuration file that can used to skip the shebang line of shell scripts: when the first line of ‘.sh‘ files starts with ‘#!‘, ‘headache‘ does not modify that line and considers that the header must start at the second line.


# SWI Prolog file
 | ".*\\.pl" -> frame open:"%"  line:"%" close:"%"
 | ".*\\.pl" -> skip multiline_match:"#!.*" multiline_match:":-.*"
Figure 4: Example of a configuration file for skipping the shebang line, as well as lines containing Prolog directives, such as Unicode usage.

Figure 4 shows an example of configuration file that can used for ‘SWI prolog‘ files: for a ‘.pl‘ file starting with the following three first lines, ‘headache‘ considers that the header must start just after the first two lines:

  #!/usr/bin/env swipl
  :- encoding(utf8).
  % remainder of the file, that can be after the header

This document was translated from LATEX by HEVEA.
headache-1.08/doc/manual.pdf000066400000000000000000001114531462110424600157060ustar00rootroot00000000000000%PDF-1.5 % 12 0 obj <> stream xڕXYs8~_)*GdIg^@QFi1lbn|_XU,Vq$]%Lw_ט nit,WHh]w|9K~36"[rSEtQɖue:5g)k\L |dWCWLD$M`izùǃ5cJY4, )*%M]MS?:ѯ$9تՁ==ۺorCn`?*\X7^ 44}3$Rk?k{?%Y NKsJ+ا:[W- dq/QTd"P<.Qӿ˓-23H  ӏj{[H4Y0?̈́2m̟mRJG"E,@V1H2b غ&PA?Nrl훫%G Tڋ/("ɻXe_Kd{X7 =m΢}!(Ȝj_O6b3,'KJ,祐[CE!yݛ_ϕ$H)H를Y`"P XGr >0P DRǿTdՒP#B:B !%zy`gCOCKd=Eq 9iRy~Y)ǚ3>e%/HI5_k]. 5,:I+ِ~"02'%P X`xT7Mcviv3鎞.nz˾. WpXnփE X %Gf*3!TGlZWXag>oR\J!HIe ~vxݯ cnN95% O?Pmi4oo?*9Eyz,DrYcLw>JufcT"&-պ&Fl !-@7鋟ZGͭ!-=mQujLnqQoG7k1\D[0c2l|ݶ}=ẽcv˭]/͔h ,\oU'7f`ZC˃ﮟ'㖤Ucb"9YĆqb$d0T:1J }]]4 7.:5r V CqAx7Ì\Ou^)[EiQyt53݌IgfK'hOI{99^$w=b`&M+,+A< Y:õ?B%z.78^M$|zm`K&Oh;m<cT'[,>bA:,7Ϲ\qh ͥEV`LmV]'jeȫ!G5r~PM\Ue7G&7e2^C g$ߥ㲷w/D- endstream endobj 16 0 obj <> stream xڭYoܸ޿bq,+ՇCps[u?+WVڈ9. 8 Cr8s77&&,-¼O0m>nBY~as LmNPԛ_7,ɋӹIT 6MU-VEK`PVdU]],0|D}v<1ꡬ;v ]u5 n3E*)z/"¹LYST[u-/t#%d%,|Y"LAZF\?эq`CnZvf K@ߺ[ i m`W;8 / 9d^,`otI<ٞ -0saИO`)IaL$oEY]:s r j\:v {.;\.‡чM6dq;]<$xP"[//4.ې\4ثV5e=1tI<6Y"0yQ,_&X4!$+?P>e$hڞz!h`MtC}@cgb y4CV =y ]sePOFK4VRDș}y*%:" D6M;g+ (3 \FhyňtJz^4=oע ʽ@wkj4s1gmo&JLH?KqH42,O49m= ~pM9]K0q^|d`4XP<<1߃%+̖jk=7]}E5Sg|954P|9dwˉU9nq:Ռ\p){£0%Q E>e,i>C@)&e^]ƓM5sҙMi貀 )gi֢cH.\%g*E+C =(lAo1W JFo !Kpb^ Fr>]j jV*L#d4 7k0Iբ}2ٺ_`\CCX9Ռ5qCmx,#Uv=Ҋ{\F3 `-_`YX ۮRl!+9 ?!sSE@G(dQ͓vF? t^SY*A,)+b1\lMT;ó$S71" |Z,L:Sr稟9"qIZ(|FVp* S8jU6+fXF;eh*‚B^E0r!tK1Ê2,lMzǶr%KxD>_d\;#'PEKcY)2]aP&Y(F=-fȢT6Ji<WBף1:N5)h @8QspEˆ ]RصUiFMIy2]#cqg8kzoO%tU cU9T&$~;N;A/uH5Fni`r5Q$u;cA6@ endstream endobj 19 0 obj <> stream xڥZs۸_ؓ: ɥIΥk<Ӈ8EYPBRqܹ??$4vB.|#qu*toaoBi-I(d,2iE"Qxq)X$q 4q1/7jTzq^$ZDQf;"Ͷ=u;͋/7XH_(-aig-'3\?umyfWgޫ3zʺ>oytz{qf8]Xi"Ȓ9F?џuk[=@1\ذYQi>盇/(ck?K~/R B|,Q>f_uYS>p>✽8_?3Ld?P*=aǹ~b6(ϱyw3  82 ;4#$dE_ P (ZH5ߗw /.R (oU}r_V}YKԷT6˦&rc%D$:/c!#5jG d"#B)~ "]*T2Oy[z>%DWC(uˇ>ţZivy!G!GC CsK.y :AJ@Ix@!;лvW5k̞CnZz@H wbhh,>gUŏ;cD `%Dбf3ԡ 7.Sd ٪h;aeh@^-]aR{AE3754`D0,BӶ(,6=˾ Yk{*VW +NR:QlizɏĄcK!:[: w$zm\!HR< }ȺsA8t@`ٖuxtGJ8$B^Ш;ڳ/W!З36VUPҧA4PQ |ʎ~cՁ25 uЅsMbؚ8u Hh o Hs~BTMƛX!p!p7ԨA,Kt]4 13>&FcXpᒣ CڌcDݕr[m_$peXKIH\J~C**5G; -.H 8TMbh9QMC)@ VC@G,Ϯh$d3 <[ J(XAR)jx(N%j1o } 54r70dV+`glKAn>F_Oюo^h~S V˾*OzU)Cɘң(P9qQPi[0ыIؿ;IC!g_d^BM5R fE.X kGo@8>(HÙ >A-ySWWS%MTP%tVVJ@gCssǙYƞቜ.+kOZ eQB]i@x:OWlyb Q;;>p{Y 3͖8Ӂ( S~,bi\8,亙7PrZk)e} pV46-:g%g`1u M9W RgS1 Ae"ĴiN3T~tmBHC8Qn:IT&2&P HH /BAWtv."/fEdQGNԙR2 q i85ij-8ttI< ^)i"Gg`)E2#6 %LcD 1n25BeoA>`g+Gm;T r6]m)|́azʜ}|17_iAgX/Mhqd6wԎ,"3A<}14n0 sCNǤxy/NU>ynJ;>$}kBM&T8pK?݆pX;Z!w]X:`}44>g?k"/zK _{i'c]uӍb!CA Ǖ=MRKax/+ 9*OxMC[5|D:8cLilXХ6]4Pxv;IjE^yC+q[VG+lkMGFsGh|&-q}4y4>B_P{#>hgqT|Jv(RAusK27IJL8H20sS` Ɂ㔚UO8FY0\*i<C^^0TCiv`t3, ֽj?_{Q)hy.16/]{,뫢N.ݗ|lח4+n}N,i_i[l5&0_kc?hc4.KbVeݐ0aB[D endstream endobj 22 0 obj <> stream xڕSMo0WL**%U{j,Z5Y&z֐E=t3o{wC& K T>w@5܃(k -(Sc'5\=H| =eADR&PKTP eT̷M9o,NP|9oBAS?2O?[#y?3e[n iFbrR\k!jn8G[N~?jkXIg&[k=sHQ\[rJ^xIΉĉ\ qd> stream x]MO0s\c dİ`\5[il"mS=xh;;I%$V R Z(ݖO̐:1&ҽ~WùitAȶ9pjԠ(@'.{ǻnZF؝6Tګ1?8r h܉ka-S#"MK($Ŀ^%EN=!ƇoH72V[n~]0bY*kYU|Y endstream endobj 27 0 obj <> stream xmHaּjΒ"vBdeeM"1KSRf[شLV kT $gFAދ6 <hAmJrYlɢf^|_;NNB BiD%e/Cc]u\<ڰżRjo2pR8<b C/o}LVHcW?L]}i/m}BoQG_HD2[I=јm1<@}2`VG⢸|~48t8/xlվ)vnG=!rgJu{8A(t.t#S~4d endstream endobj 28 0 obj <> stream x]Mn b?I"!K]Kn80N-agw7.}c4**}Q8CkeqV"kz9/+?ˡ5,hi_pLҧT&vqtYWE}f*ݍ Tp Vj< m/jWc~p@=C̲̗KBKrT8Vm DYf wÕs'[D5IXǞI)3 ۵gbσ;:MP5tdeV,p^좹'#ҟ|zh-?~锕 endstream endobj 30 0 obj <> stream xڵUkPT>91`Lݵь䖪hmBA.Y/., +ݗmY] RRLb1i;hMMYf:t;sμ=$=b6D%{?lR⚧ZO/JNDq?$rR ?Ku _e$WCC#5B2#S/YNu IxhVNBL%q2}B%/ْ}4B_(Y=Sn r5_ +DEBgP%kzIL<FjT@nubv6OXu,dyi"qޮ=(I&/ C`3k7g:{ZrthD`*KGxT6'L܃S! #=< º)d͖<fZ8砷YՐ$R=֫r]n:.\P"nMjK=4p7h7\~(r9j! oЋaKNL[Ss؃ͩc0|<9Eo;f-&`lPkT%*Y8{'Km _#GI,(fl>QT%e9orLbJIT5 4(? >D>b՞OMɛ I'wm<~jM4A=:[Z5`0℅|k7 cp\Pk!? mКN/,h3(K\)ɯg}B?İX\쫦?j(O/ C&'ϠUut{",񬚞mHstj1vYm ;vH xL:HD̡4Cyd/K=R%He~#oYhOQ<͍閃"\?KW3I'l}|EY,b=/hW-݀hѣhgT6RW"G]#`.@,C&0G ޠ\|_|)dd qGRVyhӺ6: JW]k{I]f۠YF tRh; V*'lZ4nΜ%M^ɣv\ɽg '>2 نSpZCd*ZmXL-{. hmʳeYTzzE"MSCl{F?6?"s ' endstream endobj 31 0 obj <> stream x]n0 y ;MZPiBBZiڮ41QcGeu?CfG ]iYpkY弜*ְ<|3NΧ*@aG $˹7iơB09NY|W sلHs33pV.p2D+2y ZK'Z딥Wx\0Ns6M`1Ł3kϤɂ&'=oԛg_U)t<uL^7 y5)L,w7T3 endstream endobj 33 0 obj <> stream xڕV{Tg!!3"j N⳾:VK$DyAP ! "PV**j]k[މ=3ߜ{wXF.gXUXa+B <"OvJcV"2i|,ð3GЕa`?|`FF2rS3k,/9 }TQ=eTE fxy-R/4jZctdHob [tעųg%J0D-:C7FߊL4FFڸHg=&%# ꀄHC}OeDZ/O8tE>h#iٙɐokLn]|q2Qz2L\sˁ!oE$s̙'ؠ$E\|IYdFt8LE!Jt;gPeC6!3 0:rt[@~uJ3 8L{~mP\R:jsoO voF'I&cɫ$DDzqF|"Únn%گuGǃ0eM~A^,$9XS2gl>TZ]\kQ9F$$}5B16  -/>oRCT}_7G< c=JH1Gu8ζ uI9Kd\0q_=x&BMn}zZ{"V!siUَN~h~ֽPǵ]5fOna?촲Cw]vŶ;Z|\!hKe"-M~OKd詺kN,. N$OvmhfTpXcA;t۷J"pm>sȤPLlhPڎAk$28 EyIRèɤ"ӭjOX[ksPN͛~<=-l]Lܕh$uC%(^ [*K@&Cޫ֧ՊХ#CKq*uwlO(ضYw&->꛸Wo W\07kʲh+qEO_ ~7OM„[72C@yDu] *%^-uYt 4GbvNV Ơ^W6w4u=Ljs d_*)P{7;Kk-OKD#rq2Θ_QCH@j_. +/q| e.9d|.G$knpd恎9Ly;K\D_/b`zqkDk1X]&5bcf?&d d4yL_?}LI@F;X5u'߯vКx06 B _'H'8.>[Px¶]Ýd0iPeb49s Y đi@F`<Oio̷ɜK U 5U j;OBpvȭ˨Vx?2|G"giպeC}}(b9s$BMVlr\Z2>CQ$oD *MRȿs4s?}[< VǮOls~:k}4\{Z6'?pwxb.M3o`=R(,{xe2.oѹ5窠RAlq00VBb|$Q?|{q <`oqy-Uϱ(&,)8oʄ(=B vAxrpCl Pl6=\ɞw3KsJ*!LEKIafhzc ng(K/ͭ}4{k[:(UʬR`9nد e ١-܇nCJiRK endstream endobj 34 0 obj <> stream x]Mo0 ;M]%Tr>J{ؑ!z迟v?1$~QnKM`m p P4{6_jZ c?c Χ] \q.}/u;4(8N.flW8T7c= e ؒM ^*e&.@7[.-Tcr Rb@^3c 9s1xi"'WĬV~f! /<"RbEђgq|P!9Ix|%_;=;[uwwKbC]:D endstream endobj 36 0 obj <> stream xڭY TS־!{Jm}7hmj-hZ:y" @A ; c C@@pjyOZՇZZ'rݵH={o!ёZ:y? U]NGŁ[(byR5nyp.@(Ǻ 62`ɓƸsw% op[(%- 6rjHllԔ>')tͱ!nc[7͉u[' tylsf,J(w[)PAtu+)8aaBsjp5s}(ՇO9SA %S,%\!;0]j8>5IFSRxjIM>PLj5CͥQϨBjZB$-Q˩JjZCSS(HlrP,tn~xh zL'L7>>>o^Q-; 65M1#Nl7-JJ:]G\ޮn5MN6i<@A p61΃m9#AQZ:!Llq\UMQyecȮhZ̬Ɣ JDž吶p=O  z}P ^F)CYD?wDm\2DJ/J$C*0 "BXatq ;_+..[uokuZH$zrwϗ\-4n/ת"a+jM.(=k, DE 6~_^.xrJ4`H,KZ C@޻7Lڨⶃϱx vHBq p<`2WwVdd__mFVmY#OO³@쒜Z0 uv $;3+M[PP],摯=]CAV^ uIRXG"`LufђS|T*D5h { .\p8TFDDDTTVpμFaͷQm!]ff͐+_0wذ92}q|c=Sw!:`p0n- ?(C8 #X{5БP62o9L0*0,mH'!dG@"Dm]J0r0`rrW.5)\Xx a&IjzggB_c?E;s ~rE";y}4na04X!St_k:̃S&KᓵSW,+pD$0g<-FNrQ,wAѣb /-.q/蓇ӟ1g쭪S >ƟKkl>(lC )ڥѾ5r]6 vtw+Pj; 3'WfnHa7Uh> ~p^|6ޏv&`ҋ.j1CkQhyE~سr$w3ݛ%4X! SM?/F-[I,4W *ff[lf.m>{c<,则 xXȉBК ꋯ AvFU7^}4:XkeKHuB>`;P]E"2+,κrT,Pz!X 1aÁ?;Bqc;'Q p>d{XM`UW._=e/ aدCpISr`ꓟ$$2K#7kR Cˉ|XG',@Z&ɃdN m߁u,kv#RvzY ӽoHN`ht d+95In590Gx F"* w:: b;ٗ\|gr<6 u)aT*y*Gs(M +"jE12Q$R8uysfCzw-BFT -1 RKRp(~"4,ˋ1GD;wYr$<3A-T &rțnAZYD738k^* Y&E_Fqti)!$q$GG嫏\$EQUZmZu):/BYkgN"`zCKiuy;Hg$CZЉeސzmNRY߸#r/OoM*'YD&$hNcvv#Q,c { sMi]+g% ē9\@P #*kv׫BK'Ο_Iέ&u ZN]7&/%% zi[[Q.W?B,v*WEbRFW|uf33l2G۪-:2M~1=cKιJf ŇzbG$1r#Vݻ}xC+Rk(w7  ֒] eqF5Epr_Ձ6{֍֍!V*|߈J;^eCc̼k=&" .e|oC^ڴKnV6}*Kgnm]ͫ*8 vO?8E,k9?{4ˣZHiڌĕEϲxΟTЁN>SMPe'.3.@Ĕۯ3Z Ge)urrHT-ϟWk]9@!\K~IMNѨ58oB#.ZuZBriC ~&+/h\,sfxxy|M~ J=S`=h4UDZ!xq̡'=IΡ^|s4x4= NUWx{&(㓄tͭ(a'Xm.6 Ct;Oժp;:Uwf(%L\ُ Ua8}HdH/$Ō܌<+Ծ oɖ6)8ECF9"@dw+:{g] DZn6F+ yə|Yv'NAeg=W{P)C.7Ifq]7CVΟQܔZ}_A=(ݽPRf:Z+EV79du{rj4ɴS@+n⣏z]ے'|_v VMoiVڳVaL+$ߌ( LRSEWsU~t%Y .#G| x8v6=}`!25kq&Aҗ APUbE`񥶌338ElCka> stream x]n0E| 0VBH2M:a{_U")F,I{r >mmd"^XH a<IBĝK2 2B _Huw`N/MbTwhy]G endstream endobj 39 0 obj <> stream xڍY XWמL 8 .UժKAUQUٷH;}MXâwE\q jkpk]VڪKasgnΜ{{eaAD"Xt'gi;3SBl0^ 05 7^-+0u ؍,D"&\3O_) -is;nERnvNn^ndg.pGh݄y^AsN2%P9vޡ^vk=B<;ڭvqzJǒ@PSis f\}%f+VY̕rS1}3ʜhJL R!5F ) 5b)[j4Qš;BvnLVw'9g!‹ zJ3# o"[@h+?dB ۰ :2y7USl}j0GO9Рm=iRDĬT4JLp;1GA$dGԣmqVz`#>:YNM[]t:)*/LRKV .F9œ`2~;-IUy|Q;cꂍ"ODDy$%"G6H)Cî 6|v]dij+kQF[и%j`N[)qKʚBf{]zKwqِIgPu]7jy+UdhXnnv-R? M{j9gYal(SDyR 6i LdI"@YՋ^tEǢQ [ǯ`G ̐# rewD4kox#>Q/X韐'_$T 5 JYcep2gt͵G (iT To0, ƯJ9tޕ׊+ d}ڏ\4x lΛ3k.L[U0(>Hki`nu6qp6G.zCw? 9ö;?bTO>y”焨SzWb7H@rZLbX$EO,qh+YـE.vGq':.~Uw 0găw`M&+]#XL|0 G sRV'-P[kWMOEl^vQ.T@QBA\y:HU-S: >`%61&dR.2yL@;y4? }(3ח Ez;1V˵}HOήѵ^_?Ô8<=ۙ!?{7'y/$q=j ѡ2)D>8[As|-(/ůax@VL.(H8/_Xo`05Qu':8WY[;e6cG[:[l =.B!I1-qOj~D7,=#BBEʬ0wa ؆}t #HHKNT*F۪| O41ݽ+bx* !MDo.No-L3h5ݔЋnPh)[e"~>B4=C3;3DlcqW++(~#vl<` ͍Q(aχzֿߘP^j cX҅(;D7 Ahw0+Rme7wMܘu D6Cf!h_<*hl9 Rlf~7Å2LGe+k{xqw!9Vհč~x4v~'ğ *& "z6F \OVtǀChekԑ삽ߟ>'.Ԅϒpå+y=@21G=7#2$bi9NM\KbgHܗa hI #Iȼa 5-lG5`*=4:u*TeUKu=KBߥZݳp``EZ䑕PXHoQvIFL q CJֱvE|0ӻ(8V*w3Ya1cN0 Ѫ"ҴZm( 53Ƙf60 (M:69Uu݉,R8܁ k, 79Ĺp ,Kc3çCJ Ũ"T,N#ڽbP¤LۏZPXA|p ۖO"K!o#5͠1H=U>ƞ_B#g_ =g[p}hɱt4@S`e8e\lOۥ3 Qp$ 7JYU?P%K ձ#f㶏q9s{[]ʁ򴲴r_`cq4H.k篏 b~Er/g$疻z4CW84J+HMi޼Ѕyx!Af>Ko4퓐/?rv)6aQ47vmKk5sظqr1fJw>zt>Y%hzQ ;c{f~>>A qmܜR2Qi~a$`]ePuD0>"R/*̅@>g':qcZ yI-hsZv|U(CD@\Xj%ى dU$(٘<~:.MW5i49b21j:TrCWCV3c5[ BR a ݁IZ)ˎ! ڤA#MeH&!!3.# } ܨJ 󐛒 ư M=l5oڱ$M?[6l p;]e/uA\VBW6k[ W֤'V,pimdbj]1Q.<}ׂf2Fe6Hh`"ǞzX[l:f$m7= I鿌%O%ۏ,ϝ=yLZ}'R/f@!wͅH 8UbDRl"`f-h^^ rBP-Wg?EֈKYo@/wic=AW EȦ_XNK|KM%xؽeÁ:]=|-׹̞+wyms2^=FE rZj++#Ibz<iWc\$ dyڹӝp:yovo*z4osM Z雟CYSU;D7;܆ek1g"<7q<9}m=o]Vf@Άg\3)Rv[38u`ˆi^ljOh0]% _Vg)*5casVt!!me>%2F0bir Xfh[Z"}\V9 et@B@Y[tL/g |!45yp f.6[#wC-;,@G}.2V A%%vEG?Y!#v8mYtOn=FV!K$w!&*hb^%KsLO蟘>z2*X<7>~s4m#+ÏT{( FZ؏~_$K׃AfDC,9[[6)&ڔƳdK'|֥lŽS1uȩ=[ڝDZ&&27zhOr !" q37NKB,iuUq9Re}iIuJ2鈞{LZr!as?* J:8%Dr$_@/ 1R!ȏ)b<K~LN~Ys d9xåKW^tpoz4Xi}{-"x.ѻGH֫=^Z׻[*⹳`4Q\P{ZcYljȌ GZU l3"!v9s9v޻iĠ harڵh)RSZQ +#W1/w6G-1פMjȜIU=R8̈ iV@B65} ^k蓼) U֕nCBx0i}m _fN{n +L.O){w [KfuC7r KB0Ը6ٷg s|ǩ˞׮:x^>iQ\ڸP`É2gB905)kois`W^rGO2\$?EX@7j!\XL`Xo`aیT@#1~PMn*(Ek/\/*bͅFF !֫o7itJm ^D5 K y#:ns _ג3nfh|r}J6 QD+@Fife/s5o#}KYD LzW] uq [)N> stream xcd`aa`ddtvvv 5400f!C8WeX7ee``h- ADB ̌,z%E )Ey Ayh @k:J3~~pFB k,JϨPyhӳ_[N@[w{W[7_NsX;]y=$\{匭TDM1 endstream endobj 42 0 obj <> stream x]n0 y ;MRh%QUBSiI !z/NX;|q7qPR3ofJƋ-{d/bh4 c_!>X!8Շ0O!Z徺N3F2[i6WX=ʱ;WgXE?80gYZ> stream xڭX TSg1JicC;s/RXmj7Z[7DqRvd Ka @$'! a- ZVzjbbg6;3ciO{8rpC#t{H΍6X]fx*8q CqGݨ7} 0kI<ė?'YRi\qb|/fϲUV.YgmJ81&*gs$!.%JHٞ'{!A"~Q)K/-\쓝(I'Ίy--U%*%g2RD88q*s;'6 ⧋r8B' ?b x'+?ī:5u bDl&V"N;."%|`܈O8YSҹ+g,S_{bR@ʦ4mḞg?У<,>H#g%5l`(G5BO :8Ź.jeQ/=)+{=Ǩ.hpVjm#+ A)ɔmٔd:4i0A:z[5 JȣXT^@GUNqD1Ă,49ZjggbIX+b.l!ykhQ<0[^3Ԑm{#ԓ X֓I} =h~ z 9qQ0ʏ|9,A-h*mr\mJDX 6K{SrxVvHy!z렾s>w_ j+ wʬn 4^ R(SdOex%.z6w|mNc.P MkWCdY!c.AI*.%Yr3g/ h0r>!T*  KF9.q+z Fx(mG(=+Ox5ChPLFޘc4i;+pQ+n{5j xɠ7`WhX{ \̓{u=@VZ\f(UHw_Ed˭PEyP4Ai8 zy0ЈCLZ_k%oŢVŴI3\f i d u69ab}K 3񱃂μsVkЖ[AK A5n.2G<%Y Wл'Cy ܻon7/`ceccۙc6ެdgqjR!U&mM-MPz0W#oE }exWd2G9cv؅T']݇}MQBv-4hT^5i pG]Q s_}UKmښI}$dwR ܢЧlȂbR`mLMIF}ӠAjU+kȂ361kvBP5e6l O[Vf+=_YO6a|v`3Pc 6fgG>WGϮ dx{|+X+Xw:.z]ᣧy=>"ˡS}H?Etv˷76Ǽ'7Ґ0."!6$'/)._b`RT¤#h9, w;3_Z:%}( E$>qќf4`rxቈ!W|khWV'u9vЁl3QBP&jJIޜ#j!`W{`?4:`w E45h 5p &eٗTFJ}oyTtLE [Jހܨa/ Vt{?@,ABk]6X >D)K r:ba [ʳk^w~OQo 5L2HO4al,IZ^?G_^ߥpll=y3j YUT +(uqANZj =4 u|ln0qg;\]_Nt6U:lE"Yl|v 4jw)31ϢeǹL,tJ &Q٘bǧ n~Pm&0b z_m1r}tbˤ2Oc`Ͻ[q RZy.,rQax5T7|A [$1=hM-醬5xɀ<{*)X g%QǠ~qy_DՏEU*=Gl #}USg% 2_.U?`:Tu;4ďcWWoʺ xjMZ dԚ[[}ס37οCM^D*G^Qn}d]++IL`EjNs͸> stream x]QMO0 W8P?`J[ 4qK$Fizؿ'e?/@G֠NHqgZ$I \0xfU$*T!_Sd E!_dpe7B*NF_`cw.v=e#ͬ/( Ĥ(\zb#IQIUU&m~&ӳeƱ5$=||*࠽$Ԓ6kϴ80C5Vw#eQ*he endstream endobj 47 0 obj <> stream xemLSgǟKKUtSoeR|LjZB)oStÕ8( B8fdbfc~p#f\l,˓Os0 ٙiVcjfnFrCg/R6J HBJP.&Q̗΍̼*%(kzaE]f{dK<=}2q.nrXeS5{V#'F=5iizJr֧,k,GIGѱ-r,:pf@WkX +8n2(F̐:b,]M_7By%,< 0\89U(pBkAV%4C _.Sߵ5Q}&G@ԗ7~:?} /)`4.oPZ8?2_Ń0}ߟ nt ay 8ܧ톣§u] p,==G78~&~iP-,k5oQ?AzOM = 0QjGd`w澼и⾴DKO?&\4[ʫ\pOLD4֤w9+7h(㨓Xas?1Eo}jM/*X|V!u_4L4uJyGN-8T=;WQկ#)W5 > endstream endobj 54 0 obj <> stream x]Pn ;CPe@*<$]ƃ@ @\ޚ+8%0d-(gcI@j*M.tUN;އ~Ӄ0sqs@wF|g(ؼm4M?Jz0H;#Uﺆ8?UfUn,RnYAiÍ疼YUm endstream endobj 14 0 obj <> stream xڵX[s:~Wô20ӤziDM|H`;PgWv9I9&c[Vo.,|H"yLs5QZn*@Q9'VDb#X-pfp`d&D nO\E4RD6^D2fp.7$"ED 8=$y$1Tl`?l栁0p1lCRkÇ$=j @?h`YQL`}gsW^'nJz:MF[=:ӣG IPw眹"[Wz玾 nV.0iq7G;n7[ x u VY:,YXčI'Byu!&6.)|;-(TLr D{ï|x=%Fi6;NJw35>1~΋T+Md`Js|Ū{W"~7"Vr]J"+Y,)ji]57 rnň3Zo[*՚57hmOYXF:T* 9cV@bY m1 i*!CE'H6RVԍ@""Aix{Eol'뀻#V,VOZ!s,4)n{%p.*ѬY{Pwx,\_lhsvUKг[vٳkv7Tq|#`4A2"٬!&k;/0-ǫd_8B=i[ ߡ((! DJLI0à$n Q4_JESS~|i/l舨sF#͋;NrGyR9SΟ/z=.BSqh68y馗o$3;X8C-D_9I']-ф::D/kk&llJqYmA-5+bBdg- y2qdmt.h-/9}єNf4%*+J* @}y~xum_BU5 0rr6)f[s5K_ WL 4t q MLow#0tvZvkv2YٹIJ,o54&yEMqf0I"+ݰ?Ŵ"y"kLaT$vo0[ݢ$V]}Y$:=<>"]z .tS_nr ϓgWz0o+9!1rw'9(:H2 ]a-jRl=sHL_o*5>=zuӋZ0oz.r O+$t5\UɟA.NyjF/ *;sֳRu 'A@\ͭWN ."B3^XQ&yo^=;j&?0K&k=)=3*B*Pe4TY6A0쫈T# ` endstream endobj 58 0 obj <]/Root 1 0 R/Info 2 0 R/Size 59/W[1 2 2]/Filter/FlateDecode/Length 169>> stream x-;px-F%ې@ #{=2K\)II@zd@FdB*Iu5-b#jH NafkV1\x5,&סcr#uO] Vpkz8}M&.O:KdHb\}}DxD~So endstream endobj startxref 37293 %%EOF headache-1.08/doc/manual.ps.gz000066400000000000000000003512661462110424600162060ustar00rootroot00000000000000Dfmanual.ps\)[>4%T"Bo|O ~sQ2S9pvV" vVI%t}>s% ]8؄'(ZlPA6HdK}9_R{EyyfVyNOZYEq0?|Gɗ< &;edAC9 *NΕ#w& ܏3(szAɣXb[W ʤv~.|V%e֠s :T&swa6nsqZݺU KEo"ټOCx!v&Y2 ؎"`k]8! x܁0ĢE- ]9zĀ ʀX z $94x/405[{(/ud^.!i\PբUu`[KcSODٴjtL(owUEDI~eWv=O+44~<##KdLWLݯϯ>uFΓ\ :9n{W8ah+QЂf5Ӣʹhxf"}`)KnHxASu2 hPetx\Hi] هCl|G VyȿaGԍ)m + #Tvf#W=R|(5ƨhTx`*Iկ[8Ǖ{CDX`[7cJ[u{Κ0ȋ "FJ?^_FE͛WO`/y9\H 9*$GT#]1pT$H<")db7q?|4vJh`0tBk|'+ZHȽ4w`f"JtPV4E5M (1DSW`C@-EBf8yXTtPcE\r J)4$,',c -N)K 310l3ƻ>=#0~ɃT4տˌG(.ey,&Q1ŢOEPJ9Tu%զ"ON6HɌqr萱M&YxQ뉝E<i?YDd8?ڃO6 1BuYwQK)"{>XMO !MR :fX[~"f~|Y꾾25/ Jc 1m.<-w,)<3'RbY%kzq4Na0ɶ֢΄R`43B&h/>)7 gCUsPULCOìm̏:+[ 9+FZ Z9I^gdhIÒIh`A aЩY}5Ȋ HZ?7~nؽ=`!5U'Y !CCvtmCTӦ\PFv)#PFÆܦo%3[}sE"h'Srmɦhcxc5wvdMwK/Z{("#L%&jJ'O0ݬS*-U[s\*X*,HuV}69 5%fWI4\G:szÙ^JiѤs)%5gzIѕH"l(DA qUhw>r(͵m^9F}Ӳh9TD}Ni/!"U1T^x։;3qhr{M<.-XQ_=ق)g: /ھC,JBH *.sCR諸>^ⷆ#uG[}ǥ\O7{Ş;/#A,tC"hp7n$BEGA`53FIrs 1;"!yx "pu W]CLj/!( Nͩ<4&!ȟ&n;-!j_^,31 4Ɖ<) 5^L s|{R-JCf x.;<Ƶy7]'t `9m^r}&'y#WnDRQ{@`8iN:3&\8kt㾖{z b8 CE}FvSF\Un_˅t;GqW;>_HJ=E@W{*Ds2B^] xA -w IF] UoTMnO% ( 2RE:JRGui BHD$!}uiЁ0,N E}k⍂[z5 Wksuh&ڬ3Gu yӊ-zd0n hhƩ+YAK5n+!'ЮpP,-Jǖe= [<4֗(qb(k\syrjZ]#-u3IݑNBnX3$ŋTbc6I N[<`pF1 wOkfCyV@W;}. օ9]}a!ĝ}+|\>v_,Ss=O;߇_'cmisW.TfA;nA?~`Y6v> |K )ŷ?wɗ}$w|c?d[;7~;24*X|\w]^Y\j(ݫo?O[M_|Ghd?~BV/?/}iZi/_Ϗ=s wK~7?lݿoY>]2~lϟ+g~寿Kg__⧿z+P9~l[+(o_|/{|Aև;$ǟ嗿VWѿ~_ģnlq8>PgߡT揵>Z}O?#lO+ȫ~ɷ]?9rᓪ>~75 tU"?{>/~_{vD~?Ww>;o ?_B#gkwݏ /0}?1TWI "O ;~&~($O/_^{C//w_p/_?s_W~oc~K{᫯6_ǟ9YKYIl+_myϏU[RURߔsͯ͏ή?:g*Q|߿i,*C?o~>/?4ݳ~ /_}lֿdۙϟ?_O?~׿/&k_go81e}?۟ݽV3JW|Q[Ѓ7 oe~:SaǮ΃x?R~~Wי?|/~/}/ӇϾї7?|}Y?|x>9OJY%ƻ2=Wt]wy|ĐߜkoO~j^8߳X}VIWϳprh+Z{Ngm=u׹f^|xs^eFztq95ÓS:<:̥]>^i59gF}wП'_-C>g 8WykW58rxڻx1scWڸW>3b%kOOxR;6ÿ]&Ӥo73UFO-^5x'>!^g:B8@=?~Cq}#﷜,d|g3O]뫅O /`{>bpYsc]-9}m"b.$aD} Q\2Wdԧ:{ g˵U4wU9ާ_cdx~*'V؀{n76>$p9^qVo$y7VvUČZI!OG[% G[`3⏴će?OO9+ԫ_mkLg'rfS*$EQIzuL.v?3'ZS8C;6;x=ĊY~gdFIe]^,q=&` ʇvU+qQK?,-:o=u (_ቤL=2>b҅S^\=·f _";>\󬓍 r t@^!M^ qK2+qπCcfi;B4i0+&sq\5ڕƚ`8a$oone5r#fÓ#N,ky\;qȺvL3&ĭA  [i -U!jvbē*dD-x]ۙ_O9 +ȱ-!j]&-wk ̻  R God"IaoؚŠ8usx`q{%_I(ɇ1_Ó?{80#)Im4jnkTr8 z@H~=$&׹&UM=z1,|.Kbb=%#Y_E&ߖ0=D;jK,aoXIdZ- D A3wffL?^&6K urP]B ` ؛.ލ4E܅0=~Nj@'6Ra `dDyN) OcA:>vԬP/\C|?3lx#Kp>:ٟXk 3UAw6b%i-ޏ˂J,@9`eE} /?q[Ꮮ|yZt6&+ٔPw8 ~e(9+^%pタ|Rfvs)@y"_5i<龀*V 3g3q eR8gᷘlgՔQb굎%0Z."$va@r@^>~ Q8Y"3B4C7M7h>b_HހZLV3Ipc@t׸}#֕B*xJJ~R()<?`?rb2hvB!#'Ouaჭ^U6k"Q=g;1𽆫VW 1*.A%)`oX,JL{,i<lNP5_H8$HJ7d?ptQ_T>z1{$s[ww}uBU%6|H!M\O"5ހrx@`J H,-pz_ԉ$6y!撁؈!Y@;澎',58{k1'XE%ƓYD〺4ȷ%.@pMr&"|0x1= h%fS] (A\jъI ,/?p>6}U`%?sxUZ'L yb o oGCn p# akݤ`GګZH9TДVep&tTxx~1WqG0`Q( ar <'ݩe x /!'VbP<42@7L#kYs;HO'`Z+&G^'mH`#,(ȾI Għ8 KMb>0 Or YF$EԀHL.{ɃCĐ .8P$ū(y^Ňlp(>Sn 足*O=]dz+y_jDE"0cY:XE[nȼum&ƒ|>I^¿G‡FbӁǤ1!Q1GѤJHez2x.^::&2 |h2Ncx_D"a>2*z68v7'\Hm~ cI__,G&-LҞU$`x L p(=m/yxlx=.B@8`S460\.vh$rU%ɠG:}Y;4^8^/1GnBpO?2b`HΉHgíx@H`7Fh̄=1I]dBHQ`k JvvhƖH8[Naetp>?)Yx?I8 ߆lш ?w!7<.Ӏ>dPlwO =oОB<īf;hɐg 'p -sa<$H  i<ѼwZSJס')Y= Dlô4pK !(WfpK\>ņLre/ yyy o'd< ǼeB߽΄7gx`r xN~6S|{b.(aK+U[HFLyb`I)0k:lHvH5M<" D+ ~<0 2kaQxcogDڜkD|2~ί;v<>6=48 '3kQʐ@:2a`5{R!oR$hÒ=뗗`bycH-qD;0 ] ξac-1sģ`敷;4 7xd[c2">^]Py b n "8D^! Gp=8eXCĒ,ɇDAS^KhBw3qO!ӻ61/\ž[?"/~4`G=K^>K+C<"\q]DtOTw_ &q#Qm'j !%L= UvV My'Hukl9aG:|}'AF#I8p&djWyźp"8g-I^^ >1L9*pS00q 3 GLŋ'2x ӕsr *Ws5˝#v.[]xU [X@#I(ܥ2ډe1(!.zxB遅 @F"k=YSJهO&|6q֍x[פ\8o@ƭ*z!qa>o?2ytcT8dWx0aNd!&ʁ1 [$1.2[9oR[Ev\]Ce|$}rԕD c{_!IfՏI"nT/=GແJC|a}@#Oq{wn#D7uR*BD` u*8W۬IbadQ0;Z&- 1M{FX ޗitzl?Gꀐ`SqȢ7(+P99̒6P>d'G M~}OC^E~9n3 J~[l/kc"y @(-X@1~ JPN2AKWK#y8d2iS #dPpk%D c&aƬ9fsޖSOaeWYt{zknIx<:<'}ڨ77_G![kɧ_}ZX>.VD.=8n Oµŋ> B-~kQ6 ("ul11ZD]\F8P/b{u@f|t V9| A 1%oA'#'oI HTuyjOχw~ap Չ K~ ʹ^w|{|8{9;lWW6A^ `KB{` <Qxot<%aIO5bPh@0\8Jzf8|FnӁŐZqu ZQdt[ t[0ڀ=mxz,#L++Czd7(^͂;)_!m:qy%g+@U#o]c8(cFW6x3ƋL%Utr$6GBeϷOfQ=.+AyG -@*~L(4jQ2i˒p2`Av5蝕𮋽E&T—a ĚFM/fS :6]cN#^^q%J07M:%\,!WaD .D(. <8#j']fH7|X Q,6+0Hh4k/`#8 ]bxY&RE+k+`XvڏqVN!+^R3pT#\#$7O͠bKHKrx$f wX1.>OXUW,'[0.핀]Osali\o(+|\FFbgVi5Ig܇!9`,m'L@~gUJnH׎]XlȂ5xL.B\ |zeM16^+$- vy*ln㇭:a2UIV @#[n( (.gzJbba2v 5v}U֮=:sP+ 'ri^a}e O"2i ͖6Ç"3@N,g<gӐ H  {k, f{OrO` V!J<,$ztYWs6\dJ{HdE$0J6B8o@Dd?,C(< k$`c{X :žOa|Kb"3}Ozm@aUd!A`_Z-/\NlNǚDAVrFüBFl.?BXYddA`EO7z͜!3t/^x~`}?N!x3Az:pF)y `5P#x|ML$uzX*gy "vy`'β,l'{c]lxqgro0x$6ɲ] P=ݼ%Zݻzܞۋ_$=;z߷dp >,t`ݳL|vS}^AÛXieikE[ =ƳqxS:x;ײ+E< @=bvC.|M]q eW 4{4k&bDZǞ{\gj< @?;@ƒž/uLejkGBJh;N wH(}Ox/76xNdHS1&z?j_c_Uۖc{v _^3\~@{- g{Vlr,e ƛŲ*(|cY%]p @쐏.2 oe .p `衮,MB& wfω ےBgP'x)0{@h4"wAR'8=igi>;1z gbΖ9K4&f»xJ~IڷaX,rTC*BcQ~;*ċTƁE'64ݞYL+hVnD$x0m% =8Rݭ[ԳYoTh'[jNr" nۀURa`[< գ5CǭP&"ϐmLoѰg$ZE,)ʖ*,8"u;_I/LKV@ŷauòVy,ٔ ZjJ,?- NZ3Z ='99-,U]@+T èbCy=:I63k6eu  L+Wx!5O[n ͽ Szcu|'Xuܦj Wf1z^@f%o @\8!՞ek5l<Y llgM.4Kg0|ͮ) =BLL8Oꍽ^9bΞZPY"[~k-ɶo}O6MQ,Hq-{emSU{mKgƙlvΙm=#K+kWͭeoyaєBizB;_PȪbjWoeش]kyw0>V N+G*Ej-k'2\<|m XVb~uhs)le|g>!=Ta,η^9q$ջ #Q "OH]pU yVyX֛nynϨLauXg9(*P8lO#JW]8{jG[~[ca]}gGג|O;mBj=kSg$Xz),D7 5̑z[ѓe:6mkѭ|^ `ޓ^V,js#yd2J}hOmAP0~jHZJcCs2`K]xNzMs8n[Wen4h ɓy$ 0Hy 7,XIb.R/8;s(( 2[顇ͤ)I# 7 im}$. cxy~+N ۢ0 ZlM΃M7Frϳ0ы)rypaz- {R5?{'uy78$֏3\;)G#"1!˻K^cXȜ6-7'; ).tQr[Ӟ+ HzX܌,*\2º\KG`ԙPwĖܖ5[iOj[Hg9pR@<ܺ~=1rD B׫.b[nSsxt^}/q>&uhߦWk1`QnZ]؊C@|`OʀjΏc1YB]my:u\)m]}.3@#y[pLs4'(fŸۙTC4ZN/Ɵ^{uL)Tz= n}ޭWY(xVD3CM%IL!DUD<\7],kf(Z"LPu[']k_ q vh'fتj$p~.<:*UYʌ'Xusؙ 5PStc1(U˄LVo[ŨmK>ZzZ4-\پTJ~v^XefoK"yC`m}-#TÂυ [`=us(nM[UTK''v#4-scKS"|zxVav*Ӝ~V6DDzדA'|Ɏ셁T ! $~w~U"@?Av]KIVu/r MTM\g# Hzl޽.nvlh:6f:zֽ+;x'>Qo2AM-vXAm:$Ԛ&y,vktԐ6-`{gIwpfAO^+J^ {JHĮ졧_)bjY\jv{W[ԭf)KA@+fڲOe_a͈`{SMi]}}l%Z*NZů:&TPm()~ 8{Nlh&1 ! G<=:D-q!vnA}lL[+/Cؕ-ƢTa2y` fʀ=m}b##a$n5q X#QeB5ګ-l\)bl!t=U J%ܗؒS$ sUb!y]5X?oԫvVH bձyΡ`0b΄)K,|djCI tar!j^QA}DC%ꦫWICNQKW,0K==iK}m}̞ʪyeP4g Iqe=ҞLL*p'dUQ"vy|߱K` 08=ќ`sp8v۸{u̓}.\9:}<*Uށ%IAOnu ;j9ڨdBG yW&xI <ݰ|QG6n;%2UB kĶVM@vl/QtSe0, I%sTewOM#fjyy!dyݜmN<.Ƭ3_klkwX"EN&1El0+"[<,l=(t\N'!`9͌i^7AMm5P"Hh[c~0('=wfD5yX:\;"vKіW4IS}Xz?6}8#I"ؒhiiut׋m5T4=ؼbyqXKmݹ2zp_"0@/YVa7Zߣ9Ί'c=W =0blX!Pµ+[=ye8vQJr@5 vzh`dVRZGy/w=?4b%肑vpO%Gy%\Mhи0Puj"f1yŖ#ϖꂣj@ҋylL ll`UKm#gϲo"@sz[@1uVա4KxUz") žXJviX[S}G`r92  o˺粅瘓"1jY7G{CWTGakpz:\uwd2غ81R𱰝LR9%V MW*`^VKub!JU?G"a\W/]/%y(&{z(JTow%2\v .@c\P^g;;_! GlU_CV5X` ޾şA*XJxw:G ;׮>r Fwk#p"ֺDB8<Ϩ]d 3C'J`ԍBT"S) gz< ]xG'bi.b*ldԊ߱`e\rpB%>B8W4$ +f;ܟxE<1GzV0^ $%)>+ (U9KIK`0T 1hYܤyx(iP;ȟp4zo;n ^3/>m"@ivEG:": Qht7~Su$\Z kk!.KԔe(n樕y=&sڙ{<;<NGS`CYnrUO#.pg ^D|ҍ[:# iw%#N"[Ñ@Pyѡ3Dl`mCĆxK :zh<^I0{AM `8ǣRv`& SxZץڀCPOOΎ Vު_*mYZ$R|3*TML1'B%*<]v]Cq+yk T&x8&۫孶]0si.qR] p"PoO^Zji6*{ΔӇUUG,92}QWˣ8&r-㐶 \Wx}z!swXa_&&Zv_(PuY wWWzkiX8Z]=| t8.F(IN~7L9%:0zzSZ04@f=f U7{Ȑ4V@k͏mΥ>};Dz"18`ӍcQ^=8rDG6'^FvC]R~G׃H5( )ր+Z+AgkyZ'4gN3v9}yi=Uo;~>&+, ^s%|™bdn8 ԑRw;>:8p5JyTyy@!'ae 0)XTiT{u6ՂRMVCu RS봣sad"byq~YۤF5y٥Tdu:gizz%J)LfY1b(( v]{UC^u _[׳`ft~eO!_{pʊJtCyaYdgO.em+hᘹf VAAFe<6"nD<?"q[{8;E'zBH'fG] 6/ra|_񤫥c= )̹O9|L$} 6lYl5=Fge:mN‚hx%Xꧧ %Y_+rS9YBg,k%3*P*UY^Vn5$t_ZL; +{"Am\y`01^ȯSE鈓b= \Aiʌ z@@jRZ%&xZxn&:x; e? 13jzJLFDViKaNl]"{yGhĽb1?SDZ/X$j?=5pTJFԝ >X_>B0a_QOڎ)RaL0[>2n3NǗE}SeC,J,SBED/ {8r;{cC{Ob"CeJɣ,"£u=}g=͚ϰI' lt{-kĴM `-˷) xh3\jA[jIOнtX(ñ`>hZo `,SH<9&ꯞ*)J; 7yq鈟 /u+aшʩ(l <58/;y4<یJh]-6N֭ ݉Ql&T\Bx9L#X*;` K-XTy-"2w9IZ_N,5YdeTc)B|P"bs(hc߂UQTTS]< VC %i  Ug4% Un!*ت {bqF fi.pؔҝM 6%";&fWyQcWl-Q#)83*?`[z;"p#ܖ艶/PcR*J+nBU7:v]ܰC2F[*{+|endPGʾ|zpis'MӹչqAB鞹O8ԓ^mKe:|95'n]zG#G/u=J`pzc*i:]?ěȎJxIl0 8 h 7zeI[I&Uo3.żVL+2ׂQ4Y| O*>SƑT2sez52͜*'D5x?/gRy`NC s8rؒrksɓJl'F>*# '"l·lTx/ptF뷂I?z2Ɔ{S첃Yps$xz1Ąd?89pbGPuKݷb&t[tzy/HsWQ_ȮQVXRQy%A=XQQY+Gɂd:[VۓnN/+qw,-N[޿A~^rI a[wl4NHG2 V+YRJ-WV{v|yتi4OMqdHD!࣫ܖYb(IS[-uIT4|k;n@Gd{/oN~ߝ=6ȾCD^x2/.' !dɐs6{Kd<*nM3O%<Ӛ u]_/qV&yFp,P"k)-xfq֨T Aكtz"l{A$w^fZR`cU ̄duݴǦZC|9cvѰJq5cF:+=^Q녺%jDI70l{p$8L0 u.Ap֖\htp =cTحfWc44^UVm*ʙˀN諛)p~_:AN}^g2~x4c.zmk&p.̘$J_x^&.PD;VG#=-Nv϶3Az.UO,^^jiyQ`A?9rrV_r,HY`}ͯqL ;hj|J۶ 6$v˿žAZO:=UTQ 5.TQ^d<7żL>Q $-+ qčOdz koK;YʆiZՊSޱ8_G%-:, .K0/ZU8P M(mA[-y|ZR1EEQݬSpYXpn{`}{o8\Кj%96 9w[';س$ҥ`v&Ã@R7Qd@]We̓fr` 2GO|E:͎1_8ρGŁ%ώGSߙH [X/L#K?%-+0A,`Zp`˪?AEb&O-nhfO9ƱUZLH``a S)/E]sw%ttvCHUEKzUdWI@q{8Npbgelt֫V (yC7(PÝ;g:HNgul& O7doQ 02V/ZDjxV8ͳ;)Yy{@ZVLVYD%z¼;c]ٵ@IRB&1tٯaj# *Q"g1{[R'/#qdo\?HU#[ TÝa !JI91V=~v*eC"id B rLiaX`ws4B i&nHOCe_'4NޖTEU-ޡBvdB/aыd$GmyHc5'NY*GCn瓬m^>BP;T+h./ SҘd"J::s3q/y8[=a߄0UypZbyu!:䥮˘,{;4Y%J"5 8x9|+uAqdǓ*, x Oڞ ?sUxo8jl"y#&6< ,+beDݼwXȄ 1[lTĖG=8 0ew{T<{L%' 9N3 L+sIkaC9YS持h Hl<ݎEN&ä2y1'!s/KIuazOz9[ho!JQ*yRF&L' IHq{|g9g(`:1oCa)*HxЕ]YW7kn'DOo ?mܶuıʥAk`Pk툖vpM P?q*kA |fx,7BNK^(:Kp9pza)a5TңE.DaI"Ĉ۹xγשfͶ*B>,KdßIN@b~OCYOe|TI?|[10oFtOG%̄1KT$v>aξ1OҞXsؙ0GK1RH4.VF𑧕Z$H6p߸3VE޲ux@U u^bP/?YJ?>]^ҏhGf,ye}}7urيE ߾Y TAcCu&aѡ!وanmE?z& dž$FhQl`+l9-"&=ڞ%3^9'8`$Ebx?] tϩق``S~Ϊ8z, ȴ+ Cmn\J&"vrwL+4@ŐZLF7OSc [np=JTd֖G. {@^MTf|e[th:8{.Z4<9z b\sv s`a*\=U@ V>'`pyG'"K{_ f0;!7{YrwEi,9:4Jkm n#y^E:NN_$ޡ: X_;ᣀQZ uc-`,xEQ {] i^^\J1M$CCoEd0F6S8/1rq>=(^z*uNO<2D OGZ!TƚUD NtzS#-T Q1([އl {Tpu`cʃP _GAN:S,)V䨾ӑDVULh(3x /m:&ܵBWBl_2#`-I ^$"-.,c9뿕hӗƀpZ,Xe\%\8oz #NhZ(t9͝XHVPƶ퉨 /ݾiv VV2㰧=fDlBd$nw=#GC>H$Zo N4'Xq^2WJքG- (ĎC'T͹=ٓ0a09,NK26*^uTwk[u3C.uB-]NGx_Ô r٫W0ʳS Q2$(k󾶒#'X^omwr&ӄ)!(q {Xs7QVےSlX6o/,wŇWi *l:-xr;XNE@ "ŒB?}[AT;ly+-o+=u=*g>| uq;^hE97Os܊EaYьKWFT(pE./̵֭.dlnBmK Pw<XU_.3 !˯0O@shZ_vځаO}Ov*,TNͱeP?{ÏӶWIK[mb5` U~qز{,u=ţ;KhSYNjopHQk3ճ$.<. Ȳn/}5vz]ecGh/CGm^u0cօx;ahӹb \!ji:X ݙj0A$w@vcL%I7.uޮHIѸO=АN^Z[$zfzD' 7mi:4&SeS}ˎee>%P2ݼV/p6 J-h_/>I15(")>d~]-:ޓllPb!˸>1诗Fk\P\gIq` ߣ%7^7N< Ι4|̾)bЏH AvbcJs6(oԃa$_%-u)ݕJ?d Rp jIy?UN%3هp5 g~:Gv~TR߼/gBLxL0>ЩІS,Kq?s8Ó,LPS)ުyʾVC)uM>$^ g+$Q:J4K*n,B8g4AFmK/HH{ݓ1*~n''w㗧HIqQ"۩b\S%8OÎVSƳ אfvD9;i jH9 һBk-?aUAwU͈C@y&GxPUKsg\kYlעj*X< WXUzL0Ku˻f,ίИ-ydu7RȃNqR>lW ewGId-wEl֮I pϤ; =[_hP^v_fxU~J*e{5RcFdKE 8.bASomF-[=)jI $Z`6=ǗK. jډl.+r}Uإ7 $z&E9Kُ]x 66|z[e7-eD5eþgMD9M4a5?䣩XռZ bxsu^:F q<#6Do=M&uEs$Bxa5H|fD@$OB0TWf2:'SAMaQ`'pDF&ZZ<$-+u}-{|vUY:/h[u#n2 엸< \m8dKN;|N;rU+{? 9- !C@Omn*^2!2J[WU ^ \tퟭG/ >N_>?`R>{cP_Y}/WOo|S^/X=+pɟÿWo?/~ןß_˟~?&w/X؟~d?拯~?O??{:__v__?6hu5-\ӟCs,îw3Ƈ???? |as}"~~?=`e{W~/ÕrcOU&{U^Ndts%N$tsPQ>!4u0 x,ju,'./yoPS-/k7񞗊g4& ˤd㜦c el "$ u $m1 u6J𞟠rEʝD?v:QZ+ 2-9ׂN/^C*>m>(({bwY< b"'D!2u5 ;>:_QVNnPt&+Ԑ&IzRA!RVRS-`–S 8[_& D{iKo[$:VI-C{V- I_°+ Jz0 9`pXi C•Ω=ߪ>8>SP8`P."8$A 7sN9T.Juz˓N'+1i՛VҪo dlh@þWK#;55kqXuNń!;, p*'a>Motb:Ďő")!ҜQ`:DYZt/v Q>7PNk<#^h >[){ Tƨ&2,b=?L-$RJ38MD홭M|#~q}5bX1EpfmǭG=a el ٱ-}qP:$f+-= Ru0Xck=!H duhCdR,9 ́l;6RBIvY6EB60p[8B3[ں/ 3,`ȧAX+WЃTN (R g$t[ Xv#ص_z78- 'JzA:#6mYcH@<~* cB?"^2y7d$Q* =_d Bg\Cn [lΰ*7^[ChPxWR1㎩nvD7#N+X$^FI[ѫ 0U[!QlN*:w Rϩ*W`x_儽 j+JV>Haq=a3:3nfI7Iܔ&/?)ϙ*%EDa +bm(f N*E|hk)H=!|Nx%TOYr Tc.L&FSGbA({[ƗՌ:b6z*m>D_qmVyTA9t-: +Xh9'N,\d}sI"yT!Q/;22hƲ VD"k*-[qZ;gs h{CQ ; &x:ch UU:5Vb ;b^;X%TB St*/KfݩN#j@[` *e.gf>v}hC +C{ְT䳀پ@K瓎VMONE;宀윢Tr\8X֨۞iˇ0}UZ襨&Pf=_N̯41S @] wS 5E2Mĺٙuǹsb5$ g=)FVs[=DU]y6Uviyɣ[+) _ꞿUBړs>aحYT` cFw~MmQ6$b*M%+Uuw*OGd?2=È}&VvCyP-Bt1ZS0Cpm5ϑ gsxdf/Y =Dk-t"p\eXnyk AԻE}ȮARcD3Pw_zDҖk[9Yk2MyQJ{v*9 tz`7SȞfGl]Au$- ([X^ ktӵد}Pv")u=UDyVbvD)>Ps-]4Ќez6 g[HaZJ1{^iL ϲVC@x&i`Su|<G@al/ќ+4.Opn$lF(9RS6pػ"lA{6Z@?'sumVn[.fMXkHyK a ڡM((K$*]aL˾h%ar]όj@YuɩI=TtԚkISdÂ.ieK#gr[rȜ;%;ى1!CUF!$M ~Z"P/%'q Y]ya, elzMDD_s8h?;g%{)&v/Q."trwpQ&ƣܪqF㺥ۧevs|VZ90O.ҫ`QSɺɟҰ:èˆў`gX,{9̫NQrʮ2UIQqPQgr+BR0nMUn 9G BTO%&OQ[m&Vs;5?$G_֎WX>>gy~Ͽ_|4YbG_ÿ_|⇫U<-+W_g'W_PUz^w/}Ͽ%ß}/#o쳿ۿ'_}?o拯拟}˲ '?/_~]>~׻?_}?]~nq>\?~^/_{1w䟬?ɷrW~_||/> ~`?>|~~/o~͗?c>ꗿW~s|ϗ_S?nsï__Z `??|3|ŷ26bFo_},eO_|7_|?_c5E6wBrJ/~d%)[e S϶+q)OZ߮T?*y(>~`W_W w}_ÿU?o&RgۇϿ?NLhn/n[~򫯾W>v"-">/oǿ/~_/­᳿kOk>|]煉$_姟Mwh'?|;߰ _~>}"O~/>=P*GgO _|էoۿg/~<_~_x|_| ?-kcOT7(~&/.o8?}}>}ū?|Uy++|O_W?O~t+¿>}+x+;ן?|oRoͽMW_da7O_?+KwG_j!??aїG_LG_Pї<'G_T_K~/y%O͏䩾ї<_Ko~%O U'Fub׸~zt(akaOv9P/^TTWК:d))_}L+xX\5U%qIzk/azjr+i{G՚ԧgPGvտFב_鄲W:yy eh:*՚zWUPg"; e3=rfC %Wk]83I1$'ae6ˈrjCo[t {=c߯woRx!yX7 Rw+ͻmY;y۪7 r #g렚x|/zOZ~'DY(o]ةRi^8ִre,+pYÖoRo|*>:2t-ps۪HKm۱<ʞZq{y(uh籠{o%'UV-i:W6ɹ UWȁv%\JNqS^xyU':Ҽ Knv Go΀lϭW;M/OBKѲt:w< >n+sc8;EYauLh#Բyl zy:/ [iFXpnZs2t^]I˛<_WǙWZEJ};/' !y=-qJvVڡ*dtUs<Yxֳm-X o:roݢݮtfPrKבVaGǠ7I)uނ̹{׬Ls(*%oPR;OfH٦(7[:{'7E֔f&"WrN!n&̼Ⱥ)Ԝ其#/l`_$*Di%[f嘐EYcNnyzsItO%>4Bv^nu. lḧ́ݎ-H=~Dӈp+ 52nD3`6v,V(޼AWt (y*`XV~tFiybR1N6cWګ+ƔhjE89MS|W#_^1yEP5ٮig:)!53惔'ˌ/A&a^/Hʷ`IxǮ mŇRկI=(_!MNNaD*r}>yy\38^VuTxWݍwpJ@k2H4g^bgCe@r{#c9w/GW@gv{5 |}+6AJd:m Y&m'U.l#{پva];TC PԲ0zWBN"Z3`m;R.b;ijҭrU[KelX۪K1N/;e)ʻ:/7jn;Ȋ)i#ފ3hH.hi:Vn"dr;UͳQ}piwV$C1nYU'IiYDIּi'muqH!Оo\'S9`qF ۯy0ͬ-0!-ꠕh}"sE;؟.#XF*;i?A!/Uz܈* Zq؄ ȵ9T#8 3%T2`j`v,mW'.-3D LY ֒- YW-ylR$HDfׄ٣)uA&]wv1ͫtHH*ۥ'(֫$4$+D<æ׉f#ˁ$.v?u@=!_ l@k92I9h~=ӡrhGTz*O~kth# c;P+fm|I ЭhN6$GVR8`k>v*,-`"Bi\ZTjcMé?8?ּY#v*;N(-WI(z̰$G={NYı'[La}p~|ڨ~X2n=U ?>-Ƿ {j(=znp7=P^iB;D#[HwȂ?R˰JU =#r-r0*#߂Iz{ۂ] ص=N/2 [N&ş '=}&g]]qlmOJmXY!Jb3Q+QH 2U= x6⎗GyMbV&Ir|řq:,hΞ>N[-"r5ml{]3谔 j<$c.guP* /3qSL[SL>X. TϢr5zJTPENijK;ORq17sm sf_k.k؎ˆ *^O8VBQrNRFGnAbL*sD T0 k:Q*r>S,4oGY1n{AOGXH˧\YX@F)[p=XNNu(DgQqu.!ѳ]WKrAG!6@$ZO}8ٮ1=waz*Hho0xll ʻl<弐U F;mݜ=.=+Z[9NMuV@2%r݆}bqh8 Kqh˪u%`_T9:b:Dx!a:W":m ¹8b{RvW ƔG"%_\a%y1ٕU>CcA{aGRƚm:*=]qg0%M3b+{SSUccNq8Ն5OoN.HTI {5? Ύ;@bh4Cڝz#ɑ.{do(T M*+d9J,KiCPӦpL ny2z|ꠣgseF4ǛS2 @?#[FZ؇8td 0&~Y^Jpit* }{Wޣ;!KjN,OG S" XC#`-X)Hw(Aɾ瑽+T5QI59tXXO0M'Pt)̶^x$|hW^z()QX|-) ~8;p @Ԋ\PRي^=K)6xx9|q:GsFa4kHLTňb;@{߆SG{)%&J= Nw#Cw$`% OT@aJf3p ikJq9ۙˏ*`9޲xg,\/lbwNu`sHԷ\WϨg0A-@Eӛ&U9c mCJpN:4,;;m2qvhPw49:pa%>yTYx.2$MZir ult 홓"bNwXГwﷺ WqJrAzݍ5;oLաb@[t<,a.H8ȃo,[!n6y&ԛvy` ƋNN1Q([WeUz >VȂ-L{%EEVqv (JN/:*P{uXdgQE#:aUT̙++썾 ar::y=mLuۄp-뀪ml)llXGW/lbH&de -m`* -fUkst8+ȒT86_`n@y[ Eh.pê_VFuY`<ƐiՊDo%t5:=u/'fFr* g`,{ڀQovhw;=a{zKm'n%XK_2nV9(fpO6 *v=pZRv_v:"Cpګ:qpHs)IVכx*"նHpV}NT*^TLoB'Uu]6ns@qI+˙hww1١I /vS97rt`+l__~ GughS;ZP=XfJ6X/@܊igythrwe7 $Hذ1T2[m'0,1Y!ي#NJt@/kV=AY't*+ bQ:}ik8m**hU7@32PPRߖM|~'Q:۽f|TsMbUtAԿie&i%5;Y0Nu^:ax{`/L.o%}x*c2Q`/՞ Aw p/eqnuLjyFu[ +DH7]C)F`ζz,.i@Y)3}'@%rw 9VirV_Β|}}߼UVR0%e]:^ +­:T b$կ7xq*| 5U^r z6TZ{613/ǎ2BNxU`MYR!;i'pcyMr!q)"XtwN%yù-!`ЕlHg{_ 7)˃n{U*KhaZ  P.wfco㲵#;kk$$ؓ}-B #1z$Z1)2DmfkɇRiyxV{+Ngv6*0n+ Sy"OA,/=뻧-x&@Pd/mwTQf'pyo:jVj`ye dm-G2YD}%R.'ac2)Uu ω$^hڦWG?M-7ꇚM+e1'gǵޠ@0Ѵ;aX-![RṽC\"BUQ0VCY]aءe֭/^浪c¤" f>FInO&6͒)S{7L=SJY[m@Sr9qqR~jWՖ1k-<5/INV'm`Fx5nle)HbK0ukձ&/A ۈj@^ZVV=DRxQ!.3o9A#1d`C*u<f+% 'ANG:Z4|m߰ƸE`B|Vv]e͜Ⱦ}@`7reU,֔Ӯ)A:"M:7=YWVөk^4kcl T%H EXuAF sHLCpę.K˻v3~XIR8~I^p& yg5 UxgH ww3z@Uy崈sԑ":{YD1W%{XHݦcEDUޖPgWppNX=^˒]re`:H N6P_ RxqNqk(bͫ)gzsS)^]A'lm)&,z<Ƿ@r옎8juCoUDENiasёjR³&#B<[j@ޜvnSb(0cQ{qo;C}דWuxm,8s(jax3!kyːځl'qvzJ9ع85nʶUV-1GMQ'V~Fz|LiP6j; z8E@5k}Hj9Edx,jG9MvelHgo=5,sFPo,&)I,O,c| he9IryClv*=#YoTS$ki& @B?'БצYm>)j=ObǗSl J{r[z 1wA+sA 1``0ϸ:p^29A26suvVF% Ѫ9Mw$p1:E),CᔤPh7W..,y j]XY ꗼSLVk8\TQmmJRUueNe`T8+O/<席yZ&8;̞*kwL8ok%u>eGZ8KQÞCVޡߪg6 cIo G$"~T}ϴPlc">9|b] 2'BR׹4:"xs٥p4lFpTomb<^TݓI%Y7ou*ы _OBȄasJp>=/~캞""Rb;SWrsUa$ Xó٥T{]26ZL>R>fV`%)I9r]%ӎ>۲xo_@'[ĥqFlF!3M~("*2B7'`E 0uqGaڒ29V\[CyF*uC@!RysҌ`SAX dGE 6dߤʽ05BQѽQ]V_6F!zjc, eH댹҅@8ʼn('̝hҏ Fxv+u3P#qVq^q;d]iN}j_g #x8QvBT&;'5SbYPNs.U'K"C~vv Xm\GSuX8{ɕI-d14^л8{-Yq9ߒy|r:jBȫ@B N$_Χxh{nSW> hTq{c Tu,;Rǻ'nGmZ9,%y3L8В"CBu2J`wgȁRI٠goRdͩtby'ST>-sY bg{!9"ÀS9ȍ@$X/xiI`?ftVy*L얿<1¥!UGuЄp⑚V"/X%.F1ܰq l8Cs":Ea(3@2C8K>Q$:񱂰@=ptNw`YpG"[%ztAHwdf"aS=f[ٱt*\ Mi@nmy٦R%Vyb/mmI&D[rPxs;wCwU{uy=G,$GaXpCrܺ$*zGu >RQZ9K)M2YS}רVػ Ob ˋLsqSYՇ`Hd#8,xցE9C-9"JR,K,ݞ=\1uk}->UgVTI/װ#Wte6E$w`]EL8`|_N+{Ejb9xγ@D~mx³7 0v؎ K]9q4IuP]*O% gA&K:|_@T5ELLg@A@Hw?2bQO=&yi U;z{Zk@@9[R6PءekhȢ`*ugz KclrvcqfPTPa[N"\0R쉓@%D8?6uM |kn & ODBQ`(}-.xqW}ggaaST.Iѣ Cy$yPrı?M(]R0#~%m*.\sԘ.-fɦ;pSgE$Ky3kX#|{מpwhxx: a*qɦMSZM660a+@vDj_=FeD#Cm<,bclN@ضK 7g-ʶd3NN[iu] T7ʁڐ bŗYq{E"7o4Lڠ>g 8y4.\pcv%u .K`mkv!|gZf,ty@ :qXtz>2u[ &/rH#V)b$I Fb9 ;%v(A{]\1KIjWkoe[m~DnՔJNjN8ĞV5Ԣ4iSjEnǀT(v4,= 0$^<>l+Zt|vԫ?qR}NQ1ﴛ#덦md]բ\Y7nWvhЉ\@!}ɎBf%"d;_sTqcS9U]`@B#Q-?pxtq6ߴ#KG>vUX='6(ie#C#>c@M}k6 0fױeĘCR;Lb'p&^b 2T;Zڸ;:15D+LQR* d|v^pX&aGy fو,e:*8%62%z} NԥvDr*C#b{jH>:ei:h7m"v9O IQL]cq2#*@pOz4ylqqQk;^1#&a.M>LuʀGn.)С0V#nցVCrgc$ ͩr$\[rQ[fbwUrG`s*KKs85ѻcvؘGejZ R0*w.pKqU^5s~ƣVEO,1LSv b=WChv`I'ү,_Yhuo[C.;idUNgەdކm.$竌!Qe@qf8KW.vikε&'217Et.NoaVF= +2 f8 qH EՍ5M#lpӖwcM.ẗ׺\l)g]Cuv}mcG6(@dXvG1V_o}EH(őɳ; 0޼q2}lăFwu@>qXq4i9D$UgϰHK'Zn˦I0 U~[ xRtlvC~<]r|TFz.! C{:of=Z&NLC>(6a6-58L_cɴRd5F'~>p.ra1x8ƕ XX OO#0%9t_%&ߔ@>hm18d&IL؁endzchx< t_xr'vy>aºqGde% [+Te88YBy2^AȢG+4w4"U:\Mni @]Q* ލĺ7gگMXNBgFBL:zd|}WN1D)dSXG>}NT0#p [w%L@(}l *Hc !:唝n@AC ys"yxxR1kߗyЁxvC7g[Ă۶;RaFbQ^e\T:VcE0;6 rpb/}݊|>m$åZP (ŗ7^%sJwߟ7PwNBo?q?-wY*L뜊K2O ծ={do I$qϲϋ!<=5d`\#&n1يp.-=Qv{i^S6-H$PF=]pUODnCۿc$(qf.U'pS9,3gqkO.z׹N-Ia@*A 43(0o7ϲ (8W BYV{b_wdLrlY`\"d>Uz̈́B[R:(W@y"!}]*|Q}U,pcN|_6qX Z ly>Hy(vM4@:׼ɗNht Fc1Pe1 ī1sl%vBIœ@""JؗXaCTɼc [0WƓPU !S$%qN`vիNYm⽼on`Xމ 1nvUsza Jp#z4u~k,I7 q30r$%zԩ VnNLG$;/:4{ln9+- lⓔ(ǵe,:vDI1%97d]TvƳqm FEJKpe;~)ךISU߲ &"G9DۑIj: WY+V3!E|:vZŖKC׻蛑hTqIۼ(V_ -HFEwm1MV†-Aɢp4/[wձYS09Zjoo\PU;`ݢED:Mlp,lk#$a1/7;f-%GIT'B a5mq8KnhHobM'URH(pϚx$z5cԪh*`ܵ&uK! "Q}\We%k)9OZ>΄ŀv[v[8yW9~|IH{ VY6^cC7(X:پ3mS8tPy˖sծ'v(gdUĊw5(@VퟗjGy9d﫹ȇ K^l'f%#F.y;M2j Ricpj\?%@ɑL_nw[fCBT*R& pP T0)Nh KqeĀ6(ݞYq _e;fE@(,툛3hiX]JN %~vgLjYހ$+0[Q9 &Lth(Y1Gt= i(k{,ttC8IM%aIÁ *0[\ݦL)̦-\]g. U1J#bnn@hY1\= ,ys8oIXb%.k^g HjiZ&0}PQ<0i?4 1<jy{b`*5lܥ[܈qbmL!lO6piw7٦+!j 8}*t djtDny:, @qlS8R @m5}9=$uBδY z Au$!@b`s玻M1MvO6Xr?>sr{KjaA}EJ*$"tzhGU@|@1ySZ{DyUB飝;`'uOJL'~o` Qգ0o$0cdSr(L~ᰧӃŲ-IMmS)+{քk',X{Nmw,GunM ΌPgb!n2.q Gd+xg9MkfX1S@ּ7&A۞:ql` s$I ŢLZK5"  IdFGT ʗz0*|XRi cK`` KauMgggȎl>n;P}ǐd4 *GV6DKʥu0%tS=N3#nehɀYHģU 9Ǹi6XeICjˇ~AWac&/nGS4w9LivimS)POFJ5{KoÃ9WM:ml#()}::TQt *( @c8)D bcm Ydke))$bɥظ2$.n8^*D{x,AX;sNIAmXg݁f'!)^38wx.f󧥉NV[W*%3ʹljVYfm}:c t5Vas ̹k,(֠c!=d {[%lVx7;Mlt /bخ7J&p36xn6ch 2(Z&W~|GdvYu@| ;y6"" :9Jm BޣH#s 76 ehS$^6oUup V!zzܻUЦ~l)"r?CʪT1DJl2C&ۦ#UxaκaV0,qZfFJ(im7 jr2[^9vL)%PbAyE-Uj6gsH='}O |0nG2۫k&zwv%:ඛ67)A6Ll6~uNe*wH@Sx BgDu\Y*bli4jZz3}8{pqQX|]".@tMVSy G ^2 ȱԥǍ H W3)`oѲ{3W+y"~%Sp9jn_>{gde'2 3/]rEb O'V޴e=l Q|!/Z ] 9yasȂc(5JSrv"@:,~K_0 Q)B|m3k4N-٣d{zIkN ު96J,^롂 ^#xxC Z F$ s^LQw~>^jo W"sczq)Yyxxmyڋ43aQV31J^\nYK!׹MpYe^z\gUbl'[430sjqhӮEBUw aC2pF)aYݕ9P/e xCxFٶm&&ۖl_>5~墖ٮڒGiL8 w~;EX;s;\%l}ɛqNgue2V6w?boctAS=4 i`,V@\5pޯ&h%.%.'?$(iLb|)%O1'X$^`&kInFsDZTƲqm%D4ly;{u\babC"ƊC]p&װ2Sv7j _q{K%H*nJ~_křWAȦZEٜ;W{Q u;ɇ;h§utA$*y=lOydkSt9T<,fxL41l_ڛZot(ۙ D-_sD4:GVR.J8ey,N(6R7YRdTH/kT,wUXj6'YT1ѥ4"38M.I0T>+.ȥW0)$pi%/Ƕ8t)&bdUqGq X\׬Ʞ1ٛ{I8~p8?驈OB(^$27qj@;,Jqw+&*U`m1WVVkJsmfAy]U7k՝ LD,W)îR3#e}+$ʱJkȈV8vs -9N1VZϗ98]vwkIZ"5t/|4%z2g}iΎ!koʳ&^_Ǵl3X/~:Oաf&@_@]U&T vX=-?qK6N_S]r/u4L aY!sP;`z`N垉Þ-{l]q^ckUÚ&K $ŝI-}۬֫Idmҽ;?G^OX$X-۱&p 1bűDmDN9i4$}+-xgౌbNw9hxg Fn3[9PYJ+J^+%<.pe aV[Je ^){NH,f7XtlˡΎpx.pc̃"Loׯ>}ͻO뷟?~z?O_͏>_/_\?Oۿ8/Ow•I;w?O߾/ קw3ӏ^ͯ~%ֿ/Cxٝ?~˗oӟ^z_\__?{ܸ?_r~>_~'~뗿Ͽ?/ⷿO}O>~go_?&7o'۟/Ͽ}|>o_ݯ^?_Ÿ|6/'}ˏ݇߿Ϳ}w}Go޽? ߽~y}O}_ m|w%/v?|?|?|sW_ ?~/^??_~1c?Ws߼|Ï_m1|/1~xw~l{_g/qkp{_{ /}?yՇ|9Gw;݊?{9/_C _3?w}4t} _#ÿv[_/>~w__혼^_7}=y _wf|Y\ʕ|>|+ݧO~ɼ*/\¯^N?3/~~r_rhׯ?Ow?}_/~_*˶/맏?xKkÿsO? ?[nyo_ax/~y?+gq~x?߿j|+W|+>᯿y^w+~xSx+aV~xo~i~Տ^^]K?zG/y?zɗ%?zC}<7?}G/y?zSG/y<է%OG/y_%O~SG/y%O?_2~^nDŽz_x~Y+lMrKcIqJiwS7p_ kRXT~*/s+X!8;Tڊ_JUc]Yn*Qk,|VSWn"8wmu&[F<vLTST.[nۛC"۶`?*[݊i4N;_%eF!в4'V~ K)$>΄&LEEf:_N+sAoմZ㰫\U[b/IHGS ??|`*[?)?&i6evmW{9=!}Tz=:^Jz$*:WEځ3(zǪ'wٟ8o[Udz씊'KE$_U:x|ݱog%|X# 9/YR"ncHagb:.*tYnd#ϑ` lwߔt_2_mo*@ՁӸ:t|b浓'n dYfo 8Xˆ"cHrtSw9?sv`g٫+R;f1lݗ\ΓԽ0=`G%8R264)37J@eV"K(Zn_]J>5ph2d+Ip!ݼcun$Pix7pIpKjYqΚˣo{ϺjS|7~r0-]Hg#%X*jB*vhRqv*-?9b+Y1esQM)c<Ӗ1ӼEάKcWGj5[ 596: CqR ? ArUi$v)Nr(\xCI,A%iDsL-k |Xr̶sfѹAonpl. U.{<${1LJ0 ʭ[o~m¡Om{ G/.fE!|`EW%S/A~R% cDDIco8B+dfWuKO0&XUtK(ly-$rճcjp Zpݤf_r6:Qyq6Nbp3<7N ~o?w$B2T{_Y%(Y8Q$>O! 0A|o mo͆Ro1ѨJu*` [˫8n;U.pП)hWfb jan"<}#Ee5o&cQwɧm]Nef"fOz.'SXl8Y)đERc5`Rd=EL]69\ ?]`Unsi yS}^b8o(bfy$#3И5)),pzH.A4ŐIR8VJk&k;1CncR"]Nwyd"j>yMA$v]]2x:%' Y+9Uh9zbV|nAbI[nR  o1lz9 @[H'yj @ʪ~\;-%鱓lrH˞|Q[Γ)&'r"#,\[7r*vyJs`O4<· =fsx?>n|Rnr" e-F%xKɬN;l"Eʧ[B+nL~= ]UٽQĻ)e(Oa +P=`W.5_6_mZ&r]R_RLANAUP@J Kne/U7:v9N!_=uGt zuyy8ɛȒ7GXy<-'+gF@6 W= Io׽Y9 d1՗ӂC"c1c;joޮS2t'\̄rASpq&q7 -s:O%45;GX!q81G,Ko%6U0(~PAʥ[3Jv`-'T5?kXlKʆ%)U-G]`{[%c"n.uPTé,彽#S^ N%5n DAzg$$bcU;9sd ,R٪lg-#mG|<l87u<%,Iwl\wlG7ghCDл^Z0F h@' J1\ AGe>"69qQYy9"˄:1[j0BFαiYt4`q!rK#oS'Ϩ%,E,~\qcOP*FOG٣nȹ/)9qJpS1N`Īר "uK8K}TA6O~=minR)  /δIsERùD&0gq呕9zuwrq1=y,@/9RSVU | 6cĪqkW4I,n>86t-i.e0$ZH-r Egߪ; VLi%`\%78b'nDĿ Q)7O :+WƚuQ%{{'QrjZDNr;p(ST!{Q{Ԥ g(QxАԌ@PCc(c:2ͮVD+)'2bRBåuorod,l m*m% ~sp0yK޷E0;Q*=sKPqpwcٟvޛ8S.Z彔KEZvG*f{JDtI3P 3A#"qL9P@ R_qU8VgXɆx38b3~bCUXUӞq#ljֶSDՊBҦŢS㹷G5eg)\Cď%1[Ɠ㾁Ժ²,Fl / Ƹ|oC9\.m;ղu3RVĶMtS]VD*p+y8*68zl"@!dl.˕'KOldFv_k36KMKr%&5Ys’4hR+xY$V#ٔbє}Wca_J|$Gc{(NR* v,GR,y4El{Kt˵O|zHrcyw`8.5O&`޳8p{qr-_vUѻ$GNI$q]%cW~4ݡܠr܆<). /ǁ2f*6<1y0lc`{'- ;ډiSb7%e5&\4E$rHRb?F"qϷÍظȒz ^U|^ރr4UhdIkKc ԓɫ.N vR$V 7ާ'C (<\ǂi%b7e#ETD*X=J!Q %X!?Mc2g']`$ 93A9`S0P@gJs#[boon;#$Sle@Sj{f̼ j za:ա,!KڂŋۍB6_)X{H2hڻj-vg`f)U8]*t Z h MsN%xϚ&NKS4QH<%a3Ш_B)YTarnͷҟIW~e4I!wμ;do|k2Zw:j\?`c5IcGN+ gvA ݲKC)?R75.ӲF(geL< 1)8Rm.r+e!&ȕoAE*2,sh VaWi$C!Zǭf|I4X+15 ]̃'v|ZhIg[Av3c܂, a0`?*f*q} b8_Y7PgnZV&)ՔtjUP8YTR HGp;qSYN?roi8sr|]7~M&bG8N,  2rSrDbrեnD/?45 u،&> Sx`mE5nUC4Yx;7ۛO0?&pa'GG@Eże=pҖpVScO K6v贷$m͒0j(-)[$LJrQ((XPfܻ%}Jz!G1 ԫP- /h3<&ƲxvʑȆs@@C33;{E Ե]T70hOM$l2qDZ>]8ַދg^ƾ]f3xfBY+B)AS6~uեiqp!9eX@()AGµb`}P=!Dȇ(n5|˒/ y݂O~3>ޮݕ1 U2uY͉T<|yoYc/c4;om2<), :kxI<ʹ&ebvQ{zK˄vn3LE7SGt'z8*L3w;E*b]\:V& Iޔ =&:ULl޻4](@ݟ A3nܗ(v_W]T,jA%ԱIWW% ?ꊘL>!!8YaE~]-ף.DQ%=|@J qeM%o^,DDx5n\a VCT@1K<ɫ7琕)'am:TSRrxo9#sᦲ춝=#t nzx_x VSNdVX_al,)N>Rz58 <̌)*+XRqtgu}h&d:TjoJPR~vO"ObK#_YW[۽;ۜ9hGL>{ʲT{ Q]"Y֒Uzo,4nZKvV*G|c!,X~8u!jϥE~XJW-vo\if*Nӕf"{]9m,+د`Pm9ť)=v.|9VrfPڱRu_U iV7ILEqRj 4ǎGώ&#௖XP|yAbx"}l|!/ ₢\<q2m0|F.,ل: 0JGxQCiyIEV\R55^N7Jg>UKsh_ ӫ2ϴ4\GP.t|b@3ʻ+Yߒqv7 Ɂ7>E ܭhj(Gݼ%[2e;8Dk]]An}j^@9ribs}IA%<-G!NLQ?alL tE%+ 8ηQ 2']VHV/O[3ά`U*Mg ('J=G7YU@P=zxquq!)n *+&O4*'nɦ*T $LRYrlg K)ErNĬTaWplPD)o{/55te]Jprp(%*XxFp9[?R[Q!.OŦsz8DJj| +z7W{5]w}0nSp8=s8Q rHhtԦ†apou.gPwc֚*OCTvb]zf4AA8p/8'Lu.'Tq{fl#qLq?sPkUډt @UlY]}j؈ \g3KM\ RM% b/BY}BIKTq BxY Ȕ,ݾCj[],:"Ӵm̊fOtJP~Mn:[g)Ǚ ,r뭃,k2IruӥTơla&MJev)X"츔0l  Q/M X1,s]c@v: ݈(&6g#DP ^ pӉ$Mz0$*9?7meSQ<%7"(wU^[v04.*;͚W.d ZcQ=U!d4H8ngȷYh ʙ`S3ZP)JpH+r"WQ'/[i㹊WnMYz,E ?x )[TvT]ѦkKF0'0 fWk<Ɗ^ND)ZP!hvUnIR)J9k5dZ:66KZrNz/Ǜߏ Thro~-a[5fq[ @m]f)Z.u3b)AMI>58NdɕXOiە:̎aSN= kj_9 ؚyԔYKV9UtWsvMJxsWd5i rj:˪o]_ JC5uP.n2dF$)(=+̰TG(m(-{_$]oZ~,nl1r%vEIɏ9R?Kܤ Hs7Y(Wuv^g|OGZcֽbDnm.GhΗ RmHKq'sqN'4sm,U:;% 4;g2`l` )v@əX+3nΡvީfmJKq4aKfS./1NHa30 JriS$ ӸdحuQIoәb"U@VP)qŖ-?XY-exggW:?gޞUHYuU$ .BtB?4.g2iD%svUycA#Bs. 6OYD~ XJ[_lgxkcnFY< ,}3Fie>6bOrf4;W*IPd`[$&-xH46v:mZL[V㾝Լ&Q0<:WA@nk"zB iRI:1,cɼxi=`(zKhvaI)@% wVyTJ7K(c^r3?_,NÈw:95;7E(ޒ]= ],^:'Y!aE0 h,NIl#|rHjTT!5 Hezʲ8p^m8a׿_bi6%6;GSH[bJSp,X|ob3y qPԨ3s(yJ:x̡aґ,cd-^j[S,ebzNT>+J͑:uM?a/~]cޮy,wڦo\R9Ix*xK4_^]莜t+3KəNNsӃ˘yeΟ U*ʧˡQd-#<whm<\EkxEqւ9(2TJPw\@: Sf[Z6yQ?8 0Z;uرĹW=9g&"ԁueN&҄.ץCu:spQd/oMY:g{~p%O)w*#o,1K[Oq_seU!EdkX}T?lT$C =vvIx#^A *k:̯Wg]uIY}(+%a9푴9{)_׷':n0ysFLdRyʂRD6{i34 E14]FSBIe YPHm(bC5WϹj̝q%U-ɣ*ݜj[trOvDNݸ̶yqXOB` `@._pecɈ@4pp <͟l$ ӱۛл*6뙻b<) N'i7rB1z\(@x)o7 ~!a1`]>lx6k߄b;Ay6(Wc]5Ɋ !dv(( DX*k2ps8 <`(b6CdIce&H$ԗТ c]Ĭ4@qLg(0'\4!\FAS$}\FOs8Lݥml,7l'GR{o9j-o+%~crA8 q`[,Xq>%3cڜI$arxg V& X,N,;5ȗ")IIlmHY?27vo? o&g3Q\J+np 8"{m75dxkuptZ*1t{Y]ǒá4rH ̵92qؖM:F6]N $/%nQ O)u VU¡b$ %.a؍.4٦#[=;8.lR/2>90&2U,zâ%]&6Fj&a`7̌şlL J5fEXòc ;<SFǣ"b F eW]n}w =y.%FxnsI3-@XJpxd!LCf>7yG6qJzN |.s`{mTkHe^Qu^1+E=}.{Jf&c4dvvpq\MɃJ[J,9v 1GIɱUo†zWƳف:$Xv>~bu}ɑg%ْdNM#S0˰gه_DZ|ةX}j884mLkǹe~,ss@bx(],*g92w$6air4Okemn FuɃ F,&Y.OP~/< M&v7} d|["v[2 v0ػseC س`a`FԍˆS-d߽J5sڀZ oCWfHibR ۝0?Nj8:ȈP~;8l7B 1Cљл.An!SQXǜ.~Sšgo/\Lx @:N2Y#c.ExӟM;Bߝ+!\w6x MjJ~$"bg6TvKamՓsPOt":":I<()S%\ks[2/]+B"7%%)+| t܎Ҟ8a(Da3ovzv*8fSղL88yb-.G*EeDN} mc_ԌqJ{WR\![u.fGCJu&\w˃ǣ lKmwF0m[~pv6bt*J(%.zٍM_):-Ӝ3z yxSfYwHy m95(1uHqr,N\vj[8rnJ ج-E)N%m baY[llCD w}nY^iTv,ίmt{'ɔك@ۙoQ* y5AVQ ;1l XL]uYo9Fc--aOމjs!5& 6*]gہ]|ꡀmJīͼ78[Dkjs76S*8UW][Gx5(;I`ofJm)9B>N,wc:`uX@=pƢ Fg׭%խ5H,Y7L*rWm 똯9-𓱮rB@^9uˤ Rpdq;fx w>ũzFN ڟHs]} vEm6=j#5Ϊ3> Z) 8_M 9a gjuY&@7O{~-\*Yp=i3@9#Eaw8\k.)<|Rd6^ ,?{g=ʸq_MY %(hJgn6V^fà+Z=aoC5gc{]ULUzIz}Z"F nmr+lSX'qs)(#.t&?gt|Ȟ\, kRYh, m;fe&#θkAG-ϽoE'!8XA`<{a95)A17(Xv6˞/ZblqX*"j.V ;ax)7=$e09V׆%2|[lMw9͕Q cD(sdm!kU.= _i` (,j\#cᅈv2F4$N-:DӖ, m=%993[`M q|: `rSeմ,7mLSdEM9Χov f<*<5͵ s M `L^ʍp Mbie`&7:'l ܪ ZT{x;[KmV^~& o)庌a,_ﺌ }ణ\3ιVrK QO־dpaƑuI rO jR TVL5 1lNL!!Z8:W~`LW}%I$ +ιYjyq YF؊" jnSB69&sS[jG奸~sK+gb &Y ۩2I.@ ,$ PyN#T &gf1DߕJ5n7L,j uzDuJ0rH>6(|Ib10B%ؖl2NR&Zl M)<;Cn^{)Sn${Y]Z$v$pXZ(d?A!o5AA=J*, iWTj QU%v2*cp, -,z3ɗpq[y|08y3TEP٬Vb3P,Uk:ͱ[cK9H.Evք%Vnp& YS>Op"͋ 08׮ĶXNJ,AJ?7daR B 7Y:cn SNY >IANqNV^Aɦ@%e/lsR vB#jҖ6-m*qx*`Q'ne]-r@ۺhp'ϐl UՂԕgD/jVط5Efs>aݒ8.d][L*]uR˨g zDшVOCKoLBEc܅Μf+r7x,.Čڌʾ<㖥,໔Vf fLZHۥw^j;uҒd[T w˃ҹ%v0QnM<ӵ]&, ܎8" c< jHJ/PsN+jn#-Z 4O-~ 5]/ØQ2}YQ0?UXA2xm ʴ'lsLķϳj9`.ph ;Jn'9,kꜰyP`Ode1ȵHo8|Ҷ"TrŲ3QMD0!M؆Qv>co_ݯ^?_Ÿ|8/'}ˏ݇߿Ϳ}w}Go޽? ߽~y7}O} mϯ|w%/ϯ~W?k|_}_퇟KἵzǗ}/^?Fw?^~}חϟ~O?-Ɨ<Ώ_w/Kŗ~7NW?|~}m?:߽/Jz|Jx?~y?_}Ǘ9Y~|?~#?hKO?}ן玷_=毿z}_#ÿvgǯWq e||ׯ/vN~ްx߾צ_n|a\ʭ|>|+^˻O~ ?DW[募|?y?~QN?||5~u/?7|j ~W|߿:w߿Տ^Q?z^ŏ^N|^2~w|_e~ӏ^Aee~1~K:^ qne[x~(& ewY;W.eLiPϐD$(Pri+2Vxu' \iqsAV@o7eloͻ\EMNИejmN;>9I0N9ke efKFv.=c3Y:0?8_ynqK=*JLX ܝhZl4G$B{VH}vHDVvPڗ&+T  e^.X)B-2Mm&oƢR!s{d3 v~+O$|m-X+lOq+4ıp=Lњ-¹ە_Tf+~*%3C&&gkaN/fѲPTAf`ţ*:wY;غ";ծRk?o$)\-rX 5SyJ=1iyX$cɞ"d/un;on确htI/evXfe(lrM|?J;Iݖng2US\LXf9}ʒ:'f9S@",rCs)ģbʪkV/K8ٴT U.dيJQ8u• gsa-g *g:LʟμTeG98q^L #9E`=Z2:Yb!<nX69MieN5+s#hn[⬸RU]].5^2]69i}Z5K;zKfPV])E|+Av:L}paYl֒u kk,2)`3(׎e#RCyWpێ )aK)Z(Wuڌ:I2.+ېP[z(ZE5iI;-U=jPTV-T.g v7w/P|EW]s`ySH@vFwp$1!$NDg10q80E(qtT1Mޱ :Fr\7*Jwux*i!j`ۗ͊IW;JV;p. xc#lc18{Eo#{}DYټ^eA NM37RsOYDFH+{FdC@,Wep8VIώU !f'Kv-ᇧ:mu$ z2&mdz,)[V˟8fqв uD|n0AsCNNcAGX`PM tDT[z#uV[RG@uV8_o=sw\"J|C\y ^CP)!uP7;Q^@ H`;Mp6@ډGY"Y0^z3!> /tZ̶{c(X4y% F#:e>2Q=3CFL*K vlʇ`-?5/'s\9 tӻEIU۶c1 ́%ok䂕M/ 9ci[\|}9nHqB̒80r*Ke \9! [AfWjUmJNݽoF]R y2鼥 ¢ =8=k*=G<'Pk5=vDRV*~h Z,MEvR<pJu_y@0(E7dvOrjģ@XOZI,D<S#9h"f<۶|)Mb.;B1zJ4N5cϐ8P>z,8-nzܘl \xg' `!*gBTI>1ra8{Œ%-ȪJ_|g YO^~tG[`j z. 0E5p10ݻFyVUQʻDYf C MK [ZY O,4-]u^v6C[,|s)Yzmg %H>EN_9٪Qͱ)uG{eX|cx\.ӵZvB˭QYݣC\h$Imlo+p)eJ)mCTLIX} a<<)]UHigk4٪gw!v/ p(!|;븄r#/{|'ӮI(ql D(վdx@S1n h,F9S:#8l5ݣ\,m궝{ፃ39rKbL|}Kų >js8X~)'A]Ida/;/YoTLڕ]PȲXl&O#iѳe' O=fQXhީroH*~M+_jp 痺:yۈ;k5E.YOg+0 S_SZd96KK(b} *thZ# N9]?RDCAI.9 mκ>zi (?RPS"Eq]5Ё\y]َk쏔I1Qx0%J0pMk!hD¡f9™@|"?N8%mM7!?3?eI9=K׬c[QA&~D#3qcWo({XENܢčp$6: 6\CKS-d) &Tĩ D$4Qv4PوS?f =՟zkR(dy34EƻJ=LClE#yw3~s孟gYrWr:0WOK,14.Q?>luQ!Χ.)'!$w! 5۹75cfjEi .;M!{}8t7!D;?VYXO,r8Ǎk9BJsg@UIRN>94G#Jb6rF1C.M6E%%.j]Eݿ{*YYt }?|8ϳeӌx~sW,O"Jʣp1U 3S*6`Nx4rJ[mJ{[9(KvtC|*tՔҽ_T׵%WK%NyFZURi*43s0*E=.Ѝ;fθЉ$J>n$2Rq܃?҈)7GSz_k. e9Kk,\#t_i`ӱp?Hթgp]AR4Vvq8ԇ$22.o2yN {Bb^,i2M$'Ǭ?)ku#lΟ87|u̻W=|QG@T5omp:u97N̂gÍePH |<)8$f=n5sqG۷b1rj'K57|~KU=7c2l0ZA6vzTng‘w|cd.'B~OO$b:V+ `wexŞj!r8[WC!Ȟr `ɒ֞[dGxHr6 A,s+{wB"¼=z$1(ԙYnY Rr›8Ƭoʑ|/Nӭח`=l` W<n4P=lwQ;ߤDATdb[r%kJCM4wէ"s{}M*D@~Jbu690]9/Z,g8_@e섪.z>R)GĎQJ\86"y96Y w9Y=p*))ZgxvR/)[nqȹ8B/2?*SKق5 +h*)6KnWlZR%|a賱?Nh/cfirR/7x3>whmL2l"}?(8@ocͭ a֐H| ΪĔŃ*R8ǩMa[PN9+mf6M2]"ɎA۳fC\< !Ю.j;WaUI>p(Ns4ȗanhf <<.!5Gyu<[L7+%wY:O` OeY@+Cm*To݆6" FPV`c~SM=.Hvdž93MZ 'g$@ F2vIPA?ȑ\Tp>bK~XT"`f-xfN\ );LX˪lG>9OK1Bela¼ $.LfZquuX6NJuQOf/צzRٚljHOUl;͘||k^vd1 ū$&" P=gocI;?%Eb>^ӣ:A f2s{$/Iչo=I m C\ Hw?AD`MF,)8O/Pfq\sUVKQ1xo_6ʜ*-j#Kk$i0Zs<ULQQn)8  !Z@|6c*"gU!ܛ_m9]ۗ-֙'k{^ܑlRŒ!RM+E>#{>1o%TfۮبmVb5ƦN}wWK1bNӀ0oKeP,)N0]w+56>F*8upJr)0p@<=)]lN;b?Խ|3YZڏe-fԌ_~T!* s4[VY[uiRջ)y?YmJ5%eU]U\+LIO4QL'^FމL(ᒔ VlM`]l9e1۬uT5| q;&HmFAکVof%E*#|"X\]܁۴t D1(7~ TBmduvL?(d3n[oKA+{+bN0$ΩBȝW1U ȩfy[E5NLRrjP̣LmK"1eT/zKfowG:stn!e9q*P"ت즵uˉ16fKڱ*r(рAE򡢢寮*$SD),= Y O>57y/`lnKIz@ќuDPٸΙ`SMy/RO l?(qĭJ"۫gkNE s@ Mٳ"y(T8Ȭy'C3\@䡀 \ %I9]dF ߜ h?)fQ; \,N:FGbq-jyqh}`k$ϫMBc?XE"[֎ZT^.aW(%( q瑱+\K]4TˉX)SrvOcRfaaߥ{6{ߍ NA޵BpGp`v\Fʑ)x\Ie7)Ss;aOvs>Yb gHXTnUr A\u$ecsWGt,@>U7ʺMn1)u߈2b{/g7*Ѝ!Yy躌]},f vSR^i*ңzHm1T2Ri)Uw<M%e[ªM'0BO*XUO\NT&V uՈ)밻pưHsunfZr7Ϧ83[5k; We&(|IQoR'q!Q6P&ͬrb$\ ߒ/*SS^ v+iF<ơ}W>#&i2傼f|PcT6NnX̝SFl8Fܝڝّ^ ҆#IFjN2p\m獽{S]dsN4K7iZ8g&NXþP@ ﴱDq'eGWWyP7nI⧰s Z&"XsvI=.@.:ҌQ%&asq Wώst$}ia`$\t,yNAQM<:Fpy-as[ɱSl"gUA%&i2p.|kK6zrɬљR|dxv/8u5B`&SCgN*WYgU,6c~'*T&xIR ebYv:"֌ÞYM{2vC8G$wͱGƂ;OlnKrBJC9YVw;7rI>U^;hοIL>Eup&bVa*7J085}-';9RVt{ɷ 'wH愱*fV;hCZÍݪ"e=YCvh fVAM6!?|4M[JfY"x[2|,%'Z23\]mqNԟ5\`R&9%1d2>BH"f%@aWA fs.[@[n{*xN)<]3&7nNXeRW!$w瘶"ۛg%IdCn+յan^6J$*ĕ9p2 Z-|Vv v'۝rU15n1IvGxd#R{*8L 椰Ӌ8`$-J&!Gn?HGTEc-y ,Ú V侲tqWD"yE3}Xl~]j/NeOܛJnih8d`DnY<'fOo֝KkWĖ?Y pK z:V}U]))œnw&ι8sWIǛrYJR`a8|} 8@}­r<7|>bZ""_RYKV]&qUi8%9n(m&N[!yNT V:Huࢽ$rd+;G]=Z^Ss7p'99&x-M([S'ߝt2HhU> ӳFqKl3V.#TL(eYS3~ 'LR )@6ui260 %5d! uڇ8qQSu%S8mOCZΪlO2etPj~D3G@ S圹L eJVww[${k6.LN&011%[l9Noj'Wmmq[4;;j*kp8΍wkݼ1 n9|0؟p;ԙ͹}؄ЫU P}<5 `Yf|@,ô)Y`Z;#'?nٕt_ym |psr%ft b6;| {9rUKp,,Z?'[ZƉ!<*el9>/{a Ïvfuʱ+QavFRwW>9E`<{' 5*C%tf,)j<x*o}h7uf{rw&8]Z%usNΌ @Gt_8d.lY5,Fxj'VTbqC.$'pTnGV֠eCOp,5Mj$Vqt'$4IUnY>@)|q7WRSr5Ê^\<%Hee,x8yl7??\86)q67;SrrV]CՕ@.yi: ScU`VN]VȲ9F E*qjg] !\Ln,$0R`~r aSՠ/"Ʒ,y;<ttXyz+fmxALhEsl %T@ɶi3f`1+,>۽6DŽž5M;-?-FK yU}ET7qVF2{y9mDؖfq#K-==!Ea%vd1B6?9K@wskYGydž$LQq<7ۏM~6S33rlo`Odf=qz lO.dfEUF3pY/8D2#yKvpt6J 1q+4_ A%5DSSwbO܈_4,-Q*88@.bp XL;aC[;ifoW #ݱ^~uAW(f{©)nKPN2dJWBh NdD`ڭsEWaOi9 b Hus> E-Vd RWxɺbVp͋Kpn.g::B!u2KI%& %W > ʥJ$N[daa9ǎnՕ@Np2)-{n'Ѷ๝^!I*2ԏڔŮ>`ңjku>j?򵛭iFm[!H3-|"l.nƚJ`x;bwNBChWrcɝ0-G"A _s,"=&"bE(3Ae@V{1@ɓb6IGRǿ;+ՄDdf]fVN%qbH@#DN6pAP`6̫|Ph}ŋy;Hm^'뭜U^a05mϫaXKҹ{P1}JQTiƯI)LDT XJŭH斑2ޛ2A]B!oߴɁ58/aH%Jf3K^0 ȷM ]vi}o nCTUɽGYwo[ls_"VX:g0v^F)NA[b9 D=4" dub;  Q׆74Jhz@t'n97{2$6=Ek\ sNEB+C1O@C%(uIr*]G NP+U)\'T;o*1`Et%Ѥ SܧsJH %2էTt$T;%y=-ZҹW/؋ -u$%{ҷ:rT[ZbFYµE /{-'G:w E QhSSE؎d hkٱWɍA:>PQ.MZJ8ӒwgUE3&<Ec/MQ]3J(^0Q]D]b w4+{ZIibE(+Li8PnN=R1BuN4)7f=Z$9DcQw'::O)#-LQ>r+9oy.|DcbҮǣ%_b!I G4p%RCUUh%u9{/ YA;S%(VxwY)d ?!eR",[4͡_ՈjJs%—%$4Ǵ9r0F6irdTbDUHDk9tbI$6@?Z 9] Ҋh;Pvqw";Z"9CR4),e(@UCΞȔfzZmOꢰΒr3kd|EFNI쨢wT"6i1PG cQVJBZa\{lʈt$29&T)EAE)Hw6ȽQt o@iXp(\*[bY<_: W ]ώloA?q@2>S JJ fyFt*!g<򘐚xӤߚ4iL1u[3q )_^Z[I$'$*RC}e%Vj/4ŎȮoO2OD ,)H?px+`̺:SRHyqvTI%PvQT[AP76+A7@D^*QUd/՛z~PMhb]2 Vvҙ$eHm(Imwd~rB쥒 Ai 3 ǝPxJ4B@arð$vT#頬m#Kh5lmVɁ.ENm0]4j T%T !qb$I#z ׇ$bVG5=~r 92buC+ Bt*[q%!6JtyQM[+ܨ#ER4Tтt PHuH畆P^WE뤧 +{A&(~\l8[C`RH@¶i[ZrQ!~&!$ݿO,TkS!=@ukZ5MڨDR#9".D&Ō>CQP nik` (gE3%=K^_\I׈&R(Ja ,YͤmcKBq^ETA̖tDL[s#g({JSY΋$_ltX tUI^<W1Xgފ4PQG \ m$fD)BoY$.xRBl2(C(%[Rb%og+xAX-9"I4/%AR0Q@ҡrK @yW%-Ig vN`VMK/Hzi#WfLXYԴR)PܒN wAM>jR$`JH4K*䂧t!!Q,!L'Yc$0$S XFp]7N8] "TЅ J.tzh:1آu@koˎZ#2)fJ]2WۆeTwz]RvDͱΓIQũv($7DZ}L )*DI0:_%4Y-jq\"jD(,'Aj-rt@nfH8p)hA0ʭ.:~nlSR)R)t)41{[%YsY !P bQ:b5pj \F%(A=b|Ђy2FFx !~CSB_SğRII2R"q{yz9 Β_h4q%L߱ZZ04%\%xD(7%*#1R7KLn.Ÿc]OqZð(= Ӷ:qkR>+#@-̉4i#]vz/S$QqIFJ:XVIxВ\’^Zc\@IIJ`Pϥ,-<(ť9q)"h6"J ,ԍΟTH L$9&Uӈicr+019̈́.IMK!׳Zb1IX<5bbCP+QM\ A4;4ښu$J趌yP$8Q`)bf:=j>' Б_)>TL3QBJi<šL .M">jlmrMZ1jҥQԘ 9+] ,eu& y}r.b43q[JŤ QKbXEke:wiGT}{ D43 jfn9!ahM8QZN%)tAYӋnޚ5,/1"8 4'VL&UAMG tPA)wf*Y;@:As֩d֧Q..Lh$˨DnUT9)L;^Z3^GKHMla:rӛ}[NRkS:*JNNMLj СPɬ BkV ҤX@% jD$@ҹWTK5П#kѝPSҶ-Y=g)_7 %~".%t6% 0f#SVrHd<U0-ͼ:_үkhUo$髪-)j5Eq(]?)ݣ>n=^dbL*]JPnQE9e)WX۵^E ǭM)DTPz>#SIYؤ; eREAA?cz^Qh:.@ ,I܉HM )_x2XZ iE-1:J?$&NG@o8펣.ZЅ%=9AF|υwc4t@zP3~ <;u.$VHZSf%fI18.II}J(4N !=yS^_ܨi ed 6.( *RMo0B:x EM'UNia@@В.-QqAx#3k_=PT7N3J]_Lj֞Ξu#G3wZl#&"Qh!N9 u&MN$`\Z+O%<ؘV4H=up.t"@KZ躮ATQ#XYcomX@2'Ê0CA7ϑ#.j:)’%ZD]C 0XQG#+% Op)1ezpҤϢEi:‰&:ty< !@L$% z W`\4:¼:&HWگ9m sR!CtUCGvX^$J4wҌ&5e,Zbto,T&_ZN I%%YM@%z)`BF!/}%ޘeeU.NRR :.RKFY~ N ԍO̊]]K'&'G ^f}DO吳CQ!=BMl*BsWhI4^I5Y1]usþˇ֧ꇅ, f{(!fkWC[|)rȫ?l 1?WD_"QU//Wx?V+ F*ĽF;[Mn[6R?/՚ /!M mUT;ER,,-qiL5Ljfh,yˣ0~Q TFDwy1JVzC/ł^;=DI/u9NQ6ݕӵMWiZ\O_K XJYKgMguO"&5^]Q"hiPY ?kC&U .!P'=gLѫ4w=7жs.JDY~oZ"l8{)Hw:m-=>NJ(?Dx.)5N;C4Ɠ2@Jfo,;iFXiɋQWUBEY VVMgf#5M-ʎ+]BQ ! 4q CΈTUgPS3&0(ʡNHhXl B*K4 oٺ4:@Mߢ4 wS2{ߪQR8 1{+QY|62-$Zʮ+<];n:H{%R7"="P kY\]RRfG;KmTvR]E!\J Si-uc@ ,XY$8+%εUNQRQ^juiG ׊xI2"$ZR"ROiR9y_O-͵$?Am+EmZ ;+VB2"ia &,GEr>p=q) |2'%7NKC" V }<MHn51SJFY;BObçmB&U=ؐH,q)R^CLQU/ J\yLqYH<{($顦rJIV&Ptr^ Qw_H6̆ϥxbpf&Ra/M!_S] w]%(S0ioI^:\P\c|~< j jY RNS )yKz:n 4h}\KB'4seH:Њ8^")SYA^ &$eN`R1U݋ \H>dFhТCǘ[#6ޕ6^Ni [hF! CツjqL}}J-#i4;[g%Rrx]O4'q t$jS[egq n$@.ZKhKi?UX!dN&NQ _8`K*>a$LSN.%gR53UV8Qtϕ0B2II6t4)ɾЭ虢'$GC *v( C!)8uhB\ fhD)M ߶J:Fg1N;!&ڶ%˅Y`S `xOrDuZHGc8tlzK 9Hѡ`r֐Ccë$+Y5Ľ{j8n 9)u}K[!IXKT"^+ݰ#֧=܊=?1Z@I ўKM, |Yo0"ob'J]*n6@iizS[?i|QUA}#xU٢L^-~OU՟Zl+W5'}![z\#.Ix={XG=ns>Mgxoqj>K8d'..-۳}XC6Ohx2)l>mny=Տ=`O=hk=uw/J췏Q\lDg?.Aǝ~|Ֆ7w>ގl5&gwޭ9K]ѷ򸵺oY.L`s{êVwy3vw7^F`bWru;lzkr6-KͶ.^/" xw4W7͸g:W=vŲ筎]ǯJQS81q2u [[R7x7V7/>~yޞ]&2Øe"}yׇ<_BIOvM߾W7l0'rx]$[GUhSP==xD0]ȅm_k/uuĎgomN~mY 󰑕|#OQuTl6Ӻ /:ͤ7gv9~~x)jrk;W}G}m+f\2{v,a礪rF]h lO,L^Dzm>B zm~w׶ɁT~ЛlD3{kn?\{l*K}}D ¸!7T82fL7>LF .c-7|7p2y?.y{7f'{nZu?vu{$om<[)|<&} w΍ nܞmVq~_{f'6t8oVeʍDI)x4 :v[QpUz>Âǵ!gA cYiۍ9s'MΦW DYa%&6{;N8*E?Go8/Yﶏbk/2HDsKޯnϷ _/^gT82dx~xL:I]$T\O~7^nmk;]ӵ]mon`N?Ac$/OM&)xsr_aƊktOA:n(LjfΛÀǣmoĈ8#/WM&2y5+5ze||WB||,=v3>km4x][I Fp\b>߮vjaw7/'ED@*I:Ý7.miA쓜6;H_Zj'?6v yfTv\Nf33Ӛ>v\<^1N)g2maU =SUwMg/3`[ $`3ki~zX lp-N׫i`I]"yV7]<>t$fA%mzO-{~Ű'WpzG2g}NlcFas@{]4wlxw |݋XėkIRf:3@¼nApŝ(e t֠J?STt>(⃽b<>,\1"F4$s:zFA4M;HE4L3RA z'hs}7괻 ~u^h9=:zNhzSlyoWA3oGegr}w|OGh")mKջ\Cf)(|Y$M°3鞢 ^R_:hzmL|>՜(eZ?c>O焁מn۳O-AN6O]uiFC=;OmWOAAwMAwMmt@Z '? ˏ<4bO&S |ԖX36w'6pYnngF1Ji p}fnk Od~ y$# z$- u-Nd~1b#jv%y?'.;6~ NAXR7;E'rpRehx4ן>[Egm;›wَ"^&AH6 MvT#>Oî@ṟ2M+U4xN̗NU45)mV ma>̙F~ bKIso NYQ8p8A EsGP?췳]0AħsA~?sǰ—,d^F-0v5,ȗ(2ibA>,z^v^>=1A>AvQc/NK|*1*^`(fb_/m G{rUR`>>- W-0"M2z[0L3%%8)'=*z(1Ƶf囙cQ>xϕ6fk"@cf>bqd ّ,6NT71ۏƅW?8SïyCQS(xqN#ׯ?@$qujl>?ǻљ\Nw|DJ\xe3NDDt6,s ~\2l^V8Mc]WGgKvZ kv/j~-fUKtk+4âj m ͬz7o-/W*WM|qْ'f3zŰ3 LOǽ(y}}LMsHG4??&fƓ]wis7bd?ۃ dU/*Nϖ% /&#+<3Xo6 {de8g'>MxBua9&>}B_|f㦝4&lN.Gd/{I'-aG 曥kQ>*WGED{j]4ɨźՉa ?\"x,OJ\ϯ~ kO6ӆ\``mTSo5@ŵ+~A 0dǥzB/~2 6{6]EGl:Ggnz|2lbuz܂SvI|@YI̱R GԝBy y!̞X6&Z!GOѻnWƔ"Ⴜ" $HaZ@38*h)r)(eI LfaXdRkbs#akL}.]M2LM7aiū oV:yNsKW߆ :Ixru<}sasM;'@eR$ؐ 7 r}zOF>>[fu|ofݧW!o51F 8Y_7a/,Fݘ2: +}v0h,&"Ͳ>A⇂}?sX;cژl'd d|Զ r5vpCo&4x8Koj{:ctk';cV*Ĵx⺟W,&+PO!gs E q@7 nsb|ʊsT>O"PsMh*[]d6w36C0Łuv6n uןxU!B=$*f߈^ZШf&zbN#p0uqjܿqg!>__$)`F V9PZ Ǘ+Zn҉~kک'>焨OQ,>M9[up|49 v`CeU_VTwԢ8'vSt+>1H\. 7Θ;ɞsso0h3a}}wv3[ᤛi?'IUWy;:H-SʞCdO-q̵uv|'mlo*?sִ5KC]ff/cn\`0+p_LُXF70-&Y PӘLJ!pY- vbL{?7on\?#g=ϋc M ,A'mb2O&h׳664_~ۢ"'QGS<:8iy/n̅\5а:!tf=@_̿EN8Ttugx5NiLc8==[1qnnմOBQm J}o?y:hv =,x ?DnaQo߅4UЩ4ep@@r}]~+"_ܽ>=;`SψLJRF$3߮6wwKw *zN.[5M sgH>Ӆd;bI*JO6,*ivXe< YӜ$˞[No>jF{f֛ms{ۉ%Ѳ69 l,(g۳>\?uLz>c_V~%Maޏ,:eK[N|WK [hR71cGQd Lt:xc' !"´`:&Y,çVUJ"񒝕ӽrݾSN  vheadache-1.08/doc/manual.txt000066400000000000000000000230101462110424600157430ustar00rootroot00000000000000 `headache` ********** Vincent Simonet =============== November, 2002 ============== This manual is also available in plain text (1), PostScript (2) and PDF (3). 1 Overview *=*=*=*=*= It is a common usage to put at the beginning of source code files a short header giving, for instance, some copyright informations. `headache` is a simple and lightweight tool for managing easily these headers. Among its functionalities, one may mention: - Headers must generally be generated as comments in source code files. `headache` deals with different file types and generates for each of them headers in an appropriate format. - `headache` automatically detects existing headers and removes them. Thus, you can use it to update headers in a set of files. `headache` is distributed under the terms of the GNU Library General Public License. See file `LICENSE` of the distribution for more information. 2 Compilation and installation *=*=*=*=*=*=*=*=*=*=*=*=*=*=*= Building `headache` requires Objective Caml (available at http://caml.inria.fr/) and GNU Make. In addition, from version 1.03-utf8, the build requires the Unicode library Camomile and, from version 1.04, Dune. Instructions `headache` is available through OPAM (available at http://opam.ocaml.org/), the OCaml Package Manager. This is the preferred installation method. Then the following sequence of commands should install the package: << opam init opam install headache >> Alternatively, you can use these commands (Dune must be installed): << make && sudo make INSTALLDIR=/usr/local/bin install >> Build the executable and install it into the specified directory. 3 Usage *=*=*=* Let us illustrate the use of this tool with a small example. Assume you have a small project mixing C and Caml code consisting in three files `foo.c`, `bar.ml` and `bar.mli`, and you want to equip them with some header. First of all, write a header file, i.e. a plain text file including the information headers must mention. An example of such a file is given in figure 1. In the following, we assume this file is named `myheader` and is in the same directory as source files. Then, in order to generate headers, just run the command: << headache -h myheader foo.c bar.ml bar.mli >> Each file is equipped with a header including the text given in the header file `myheader`, surrounded by some extra characters depending on its format making it a comment (e.g. `(*` and `*)` in `.ml` files). If you update informations in the header file `myheader`, you simply need to re-run the above command to update headers in source code files: existing ones are automatically removed. Similarly, running: << headache -r foo.c bar.ml bar.mli >> removes any existing in files `foo.c`, `bar.ml` and `bar.mli`. Files which do not have a header are kept unchanged. The current headers of files can be extracted: << headache -e foo.c bar.ml bar.mli >> prints on the standard output the current headers of the files `foo.c`, `bar.ml` and `bar.mli`. All files are kept unchanged. -------------------------------------------------------------------- << Headache Automatic generation of files headers Vincent Simonet, Projet Cristal, INRIA Rocquencourt Copyright 2002 Institut National de Recherche en Informatique et en Automatique. All rights reserved. This file is distributed under the terms of the GNU Library General Public License. Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ >> Figure 1: An example of header file -------------------------------------------------------------------- 4 Configuration file *=*=*=*=*=*=*=*=*=*= File types and format of header may be specified by a configuration file. By default, the default builtin configuration file given in figure 2 is used. You can also use your own configuration file thanks to the `-c` option: << headache -c myconfig -h myheader foo.c bar.ml bar.mli >> In order to write your own configuration, you can follow the example given in figure 2. A configuration file consists in a list of entries separated by the character `|`. Each of them is made of two parts separated by an `->`: - The first one is a regular expression. Regular expression are enclosed within double quotes and have the same syntax as in Gnu Emacs. `headache` determines file types according to file basenames; thus, each file is dealt with using the first line its name matches. - The second one describes the format of headers for files of this type. It consists of the name of a model (e.g. `frame`), possibly followed by a list of arguments. Arguments are named: `open:"(*"` means that the value of the argument `open` is `(*`. `headache` currently supports three models: - `frame`. With this model, headers are generated in a frame. This model requires three arguments: `open` and `close` (the opening and closing sequences for comments) and `line` (the character used to make the horizontal lines of the frame). Two optional arguments may be used: `margin` (a string printed between the left and right side of the frame and the border, by default two spaces) and `width` (the width of the inside of the frame, default is 68). - `lines`. Headers are typeset between two lines. Three arguments must be provided: `open` and `close` (the opening and closing sequences for comments), `line` (the character used to make the horizontal lines). Three optional arguments are allowed: `begin` (a string typeset at the beginning of each line, by default two spaces), `last` (a string typeset at the beginning of the last line) and `width` (the width of the lines, default is 70). - `no`. This model generates no header and has no argument. It is possible to change the default builtin configuration file at compile time. For this, just edit the file `config_builtin.txt` present in the source distribution before building the software. -------------------------------------------------------------------- << # Objective Caml source ".*\\.ml[il]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.fml[i]?" -> frame open:"(*" line:"*" close:"*)" | ".*\\.mly" -> frame open:"/*" line:"*" close:"*/" # C source | ".*\\.[chy]" -> frame open:"/*" line:"*" close:"*/" # Latex | ".*\\.tex" -> frame open:"%" line:"%" close:"%" # Misc | ".*Makefile.*" -> frame open:"#" line:"#" close:"#" | ".*README.*" -> frame open:"*" line:"*" close:"*" | ".*LICENSE.*" -> frame open:"*" line:"*" close:"*" >> Figure 2: The default builtin configuration file -------------------------------------------------------------------- It is also possible to add entries into your own configuration file that specify when the initial lines of the processed file have to be skipped. As previously, these entries are separated by the character `|` and each of them is made of two parts separated by an `->`: - Again, the first part is a regular expression used by `headache` to determine the file type. But here, it is according to its full filename (including the pathname). - The second part specifies when the initial lines must be skipped. It consists of the keyword `skip` followed by one of the named arguments `multiline_match:` or `match:`, then a regular expression. As long as the lines match a `multiline_match` parameter, `headache` skips them and checks the next line. If the current line matches only a `match` parameter, `headache` skips the current line and breaks the iteration there (of course, if nothing matches, `headache` puts the header before the current line). -------------------------------------------------------------------- <<# Script file | ".*\\.sh" -> frame open:"#" line:"#" close:"#" | ".*\\.sh" -> skip match:"#!.*" >> Figure 3: Example of a configuration file for skipping the shebang line of shell scripts -------------------------------------------------------------------- Figure 3 shows an example of configuration file that can used to skip the shebang line of shell scripts: when the first line of `.sh` files starts with `#!`, `headache` does not modify that line and considers that the header must start at the second line. -------------------------------------------------------------------- <<# SWI Prolog file | ".*\\.pl" -> frame open:"%" line:"%" close:"%" | ".*\\.pl" -> skip multiline_match:"#!.*" multiline_match:":-.*" >> Figure 4: Example of a configuration file for skipping the shebang line, as well as lines containing Prolog directives, such as Unicode usage. -------------------------------------------------------------------- Figure 4 shows an example of configuration file that can used for `SWI prolog` files: for a `.pl` file starting with the following three first lines, `headache` considers that the header must start just after the first two lines: << #!/usr/bin/env swipl :- encoding(utf8). % remainder of the file, that can be after the header >> ----------------------------------------------------------------------- This document was translated from LaTeX by HeVeA (4). ----------------------------------- (1) manual.txt (2) manual.ps.gz (3) manual.pdf (4) http://hevea.inria.fr/index.html headache-1.08/dune000066400000000000000000000011501462110424600140370ustar00rootroot00000000000000(library (name headache) (modules Model Config_lex Config_parse Config Info Skip) (libraries camomile str) ) (ocamllex config_lex) (ocamlyacc config_parse) (executable (name mkconfig) (modules Mkconfig) (libraries headache) ) (rule (targets config_builtin.ml) (deps mkconfig.exe config_builtin.txt) (action (run ./mkconfig.exe)) ) (executable (name headache_tool) (public_name headache) (modules Headache_tool Config_builtin) (libraries headache unix) ) (install (section doc) (files "doc/manual.pdf" "doc/manual.html" "doc/manual.txt") ) headache-1.08/dune-project000066400000000000000000000000201462110424600154760ustar00rootroot00000000000000(lang dune 3.4) headache-1.08/example000066400000000000000000000005471462110424600145500ustar00rootroot00000000000000 Headache Vincent Simonet, Projet Cristal, INRIA Rocquencourt Copyright 2002 Institut National de Recherche en Informatique et en Automatique. All rights reserved. This file is distributed under the terms of the GNU Library General Public License. Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ headache-1.08/headache.opam000066400000000000000000000014121462110424600155620ustar00rootroot00000000000000opam-version: "2.0" name: "headache" version: "1.08" license: "LGPL-2.0-only" synopsis: "Automatic generation of files headers" description: """ Lightweight tool for managing headers in source code files. It can update in any source code files (OCaml, C, XML et al). """ authors: [ "Vincent Simonet" # contributors "Patrick Baudin" "Mehdi Dogguy" "André Maroneze" "François Pottier" "Virgile Prevosto" "Ralf Treinen" ] maintainer: "frama-ci-bot@frama-c.com" homepage: "https://github.com/Frama-C/headache/" bug-reports: "https://github.com/Frama-C/headache/issues" dev-repo: "git+https://github.com/Frama-C/headache.git" depends: [ "ocaml" {>= "4.13"} "camomile" {>= "2.0.0"} "dune" {>= "3.4"} ] build: [ [ "dune" "build" "-p" name "-j" jobs ] ] headache-1.08/headache_tool.ml000066400000000000000000000161521462110424600163020ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) open Printf open Config_builtin open Headache (***************************************************************************) (** {2 Command-line options} *) let verbose = ref false (***************************************************************************) (** {2 Configuration files} *) let generators : (Str.regexp * Model.generator) list ref = ref [] let skips : (Str.regexp * Skip.param_skip) list ref = ref [] let read_configfile filename = let ic = open_in filename in let lexbuf = Lexing.from_channel ic in try let (config_generators, config_skips) = (Config_parse.configfile Config_lex.token lexbuf) in skips := config_skips @ !skips; generators := config_generators @ !generators; close_in ic with Config.Error (msg, loc1, loc2) -> eprintf "%s: Configuration file %s, error at characters %d-%d:\n%s\n" Sys.argv.(0) filename loc1 loc2 msg; exit 2 | Parsing.Parse_error -> eprintf "%s: Configuration file %s, syntax error at characters %d-%d:\n" Sys.argv.(0) filename (Lexing.lexeme_start lexbuf) (Lexing.lexeme_end lexbuf) let find_generator filename = let basename = Filename.basename filename in try let _, generator = List.find (function regexp, _ -> Str.string_match regexp basename 0 ) (! generators) in generator with Not_found -> eprintf "%s: No generator found for file %s\n" Sys.argv.(0) filename; exit 2 let find_skips filename = List.filter (fun (rg_filename, _) -> Str.string_match rg_filename filename 0) !skips (***************************************************************************) (** {2 Builtin config} *) let _ = try generators := List.map (function regexp, model, parameters -> (Str.regexp (sprintf "^%s$" regexp), (Model.find model) parameters) ) builtin_config with Not_found -> eprintf "%s: Error in builtin configuration\n" Sys.argv.(0); exit 2 (***************************************************************************) (** {2 Header files} *) let read_headerfile filename = let ic = open_in filename in let rec loop () = try let line = input_line ic in line :: loop () with End_of_file -> close_in ic; [] in let header = loop () in let header_width = List.fold_left (fun w line -> max (Model.string_length line) w) 0 header in header, header_width (***************************************************************************) (** {2 Processing files} *) let prng = Random.State.make_self_init ();; let temp_file_name directory prefix suffix = let rnd = (Random.State.bits prng) land 0xFFFFFF in Filename.concat directory (Printf.sprintf "%s%06x%s" prefix rnd suffix) ;; let open_temp_file ?(mode = [Open_text]) directory prefix suffix = let rec try_name counter = if counter >= 1000 then invalid_arg "Filename.open_temp_file: temp dir nonexistent or full"; let name = temp_file_name directory prefix suffix in try (name, open_out_gen (Open_wronly::Open_creat::Open_excl::mode) 0o600 name) with Sys_error _ -> try_name (counter + 1) in try_name 0 let pipe_file f filename = let directory = Filename.dirname filename in let ic = open_in filename in let tempname, oc = open_temp_file directory "header" "tmp" in f ic oc; close_in ic; close_out oc; Unix.chmod tempname (Unix.stat filename).Unix.st_perm; Sys.remove filename; Sys.rename tempname filename let rd_pipe_file f filename = let ic = open_in filename in f ic; close_in ic let copy ic oc = let len = 256 in let buf = Bytes.create len in let rec loop () = let i = input ic buf 0 len in if i > 0 then begin output oc buf 0 i; loop () end in loop () let create_header header header_width filename = let generator = find_generator filename in let skip_lst = find_skips filename in pipe_file (fun ic oc -> let () = Skip.skip ~verbose:!verbose skip_lst ic (Some oc) in let line = generator.Model.remove ic in let () = Skip.skip ~verbose:!verbose skip_lst ic (Some oc) in generator.Model.create oc header header_width; output_string oc line; copy ic oc ) filename let remove_header filename = let generator = find_generator filename in let skip_lst = find_skips filename in pipe_file (fun ic oc -> let () = Skip.skip ~verbose:!verbose skip_lst ic (Some oc) in let line = generator.Model.remove ic in let () = Skip.skip ~verbose:!verbose skip_lst ic (Some oc) in output_string oc line; copy ic oc ) filename let extract_header filename = let generator = find_generator filename in let skip_lst = find_skips filename in rd_pipe_file (fun ic -> let () = Skip.skip ~verbose:!verbose skip_lst ic None in generator.Model.extract ic ) filename (***************************************************************************) (** {2 Main loop} *) type action = Create of string list * int | Remove | Extract let main () = let action = ref (Create ([], 0)) in let anonymous filename = match !action with Create (header, header_width) -> create_header header header_width filename | Remove -> remove_header filename | Extract -> extract_header filename in Arg.parse [ "-h", Arg.String (fun s -> let (header, header_width) = (read_headerfile s) in action := Create (header, header_width)), " Create headers with text from the header file"; "-c", Arg.String read_configfile, " Read the given configuration file"; "-r", Arg.Unit (fun () -> action := Remove), " Remove headers in files"; "-e", Arg.Unit (fun () -> action := Extract), " Extract headers from files"; "-v", Arg.Set verbose, " Enable verbose output"; ] anonymous (sprintf "%s, version %s\n\ Usage: %s \n \ Process headers of given files\n\ Optional arguments are:" Info.name Info.version Info.name); () let () = try main () with Sys_error msg -> eprintf "%s: %s\n" Sys.argv.(0) msg headache-1.08/info.ml000066400000000000000000000021421462110424600144500ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) let name = "headache" let version = "1.08" headache-1.08/mkconfig.ml000066400000000000000000000041121462110424600153110ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) open Printf open Headache let file_in = "config_builtin.txt" let file_out = "config_builtin.ml" let main () = let ic = open_in file_in in let lexbuf = Lexing.from_channel ic in let oc = open_out file_out in try fprintf oc "let builtin_config = [\n"; List.iter (function regexp, model, parameters -> fprintf oc "\"%s\", \"%s\", [" (String.escaped regexp) (String.escaped model); List.iter (function name, v -> fprintf oc "\"%s\", \"%s\"; " (String.escaped name) (String.escaped v) ) parameters; fprintf oc "];\n" ) (Config_parse.boot Config_lex.token lexbuf); fprintf oc "]\n"; close_in ic; close_out oc with Config.Error (msg, loc1, loc2) -> eprintf "%s: Configuration file %s, error at characters %d-%d:\n%s\n" Sys.argv.(0) file_in loc1 loc2 msg; exit 2 | Parsing.Parse_error -> eprintf "%s: Configuration file %s, syntax error at characters %d-%d:\n" Sys.argv.(0) file_in (Lexing.lexeme_start lexbuf) (Lexing.lexeme_end lexbuf) let () = main () headache-1.08/model.ml000066400000000000000000000174521462110424600146270ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) open Camomile open Printf exception Error of string let string_length s = try UTF8.validate s; UTF8.length s with UTF8.Malformed_code -> String.length s (***************************************************************************) (** {2 Headers generators} *) type generator = { extract: in_channel -> unit; remove: in_channel -> string; create: out_channel -> string list -> int -> unit; } (***************************************************************************) (** {2 Models} *) type model = (string * string) list -> generator let models : (string, model) Hashtbl.t = Hashtbl.create 3 let add name m = Hashtbl.add models name m let find name = Hashtbl.find models name (***************************************************************************) let arg_string args ?default name = try List.assoc name args with Not_found -> match default with None -> raise (Error (sprintf "parameter %s is missing" name)) | Some s -> s let arg_int args ?default name = try int_of_string (arg_string args ?default name) with Failure _ -> raise (Error (sprintf "parameter %s expects an integer" name)) let arg_char args ?default name = let s = arg_string args ?default name in if string_length s = 1 then s.[0] else raise (Error (sprintf "parameter %s expects a character" name)) let make_frame ~open_comment ~close_comment ~line_char ~margin ~width = let regexp_header = Str.regexp_string (sprintf "%s%s" open_comment (String.make 10 line_char)) in let regexp_blank = Str.regexp "^[ ]*[\r]?$" in let regexp_extra = Str.regexp "[ \r]+$" in let regexp_margin = Str.regexp ("^" ^ margin) in let regexp_open = Str.regexp ("^" ^ (Str.quote open_comment)) in let len_open = String.length open_comment in let len_close = String.length close_comment in let extract ic = try let line = input_line ic in if Str.string_match regexp_header line 0 then begin while let line = input_line ic in let b = not (Str.string_match regexp_blank line 0) in if b && not (Str.string_match regexp_header line 0) then begin let len = String.length line in let s = if (len >= len_open+len_close) && (Str.string_match regexp_open line 0) then String.sub line len_open (len-(len_open+len_close)) else line in let s = Str.replace_first regexp_margin "" s in let s = Str.global_replace regexp_extra "" s in Format.printf "%s@." s end; b do () done; end with End_of_file -> () in let remove ic = try let line = input_line ic in if Str.string_match regexp_header line 0 then begin while not (Str.string_match regexp_blank (input_line ic) 0) do () done; "" end else if Str.string_match regexp_blank line 0 then "" else (line ^ "\n") with End_of_file -> "" in let create oc header header_width = let real_width = max width header_width in let width' = real_width + 2 * String.length margin in let white = String.make width' ' ' in let line = String.make width' line_char in Printf.fprintf oc "%s%s%s\n" open_comment line close_comment; let last = List.fold_left (fun _ string -> output_string oc open_comment; output_string oc margin; output_string oc string; output_substring oc white 0 (max 0 (real_width - string_length string)); output_string oc margin; output_string oc close_comment; output_char oc '\n'; string ) "" header in if last <> "" then begin output_string oc open_comment; output_string oc white; output_string oc close_comment; output_char oc '\n'; end; Printf.fprintf oc "%s%s%s\n\n" open_comment line close_comment in { extract = extract; remove = remove; create = create } let _ = add "frame" begin function args -> make_frame ~open_comment:(arg_string args "open") ~close_comment:(arg_string args "close") ~line_char:(arg_char args "line") ~margin:(arg_string args ~default:" " "margin") ~width:(arg_int args ~default:"68" "width") end let make_lines ~open_comment ~close_comment ~line_char ~begin_line ~begin_last ~width = let regexp_begin = Str.regexp_string (sprintf "%s%s" open_comment (String.make 10 line_char)) in let regexp_end = Str.regexp_string (sprintf "%s%s" (String.make 10 line_char) close_comment) in let end_length = 10 + String.length close_comment in let regexp_blank = Str.regexp "^[ ]*$" in let extract ic = try let line = input_line ic in if Str.string_match regexp_begin line 0 then begin while let s = input_line ic in let b = not (Str.string_match regexp_end s (max 0 (string_length s - end_length))) in if b then Format.printf "%s@." s; b do () done; () end with End_of_file -> () in let remove ic = try let line = input_line ic in if Str.string_match regexp_begin line 0 then begin while let s = input_line ic in not (Str.string_match regexp_end s (max 0 (string_length s - end_length))) do () done; "" end else if Str.string_match regexp_blank line 0 then "" else (line ^ "\n") with End_of_file -> "" in let create oc header header_width = let real_width = max width header_width in Printf.fprintf oc "%s%s\n" open_comment (String.make (max 0 (real_width - String.length open_comment)) line_char); List.iter (function string -> output_string oc begin_line; output_string oc string; output_char oc '\n' ) header; Printf.fprintf oc "%s%s%s\n\n" begin_last (String.make (max 0 (real_width - String.length begin_last - String.length close_comment)) line_char) close_comment; in { extract = extract; remove = remove; create = create } let _ = add "lines" begin function args -> make_lines ~open_comment:(arg_string args "open") ~close_comment:(arg_string args "close") ~line_char:(arg_char args "line") ~begin_line:(arg_string args ~default:" " "begin") ~begin_last:(arg_string args ~default:"" "last") ~width:(arg_int args ~default:"70" "width") end let make_no () = { extract = (fun _ -> ()); remove = (fun _ -> ""); create = (fun _ _ _ -> ()) } let _ = add "no" (function _ -> make_no ()) headache-1.08/skip.ml000066400000000000000000000042651462110424600144730ustar00rootroot00000000000000(**************************************************************************) (* *) (* Headache *) (* *) (* Vincent Simonet, Projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 2002 *) (* Institut National de Recherche en Informatique et en Automatique. *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Library General Public License. *) (* *) (* Vincent.Simonet@inria.fr http://cristal.inria.fr/~simonet/ *) (* *) (**************************************************************************) type regexp_filename = Str.regexp ;; type regexp_skip = Str.regexp ;; type param_skip = bool * regexp_skip ;; let skip ~verbose skip_lst ic oc = let multiple_skip_lst,simple_skip_lst = List.partition (fun (_,(multiple,_)) -> multiple) skip_lst in let rec skip_aux () = let initial_pos = LargeFile.pos_in ic in try let line = input_line ic in let match_line skip_lst = let (_,(multiple,_)) = List.find (fun (_, (_,rg_skip)) -> Str.string_match rg_skip line 0) skip_lst in multiple in try let multiple = try match_line multiple_skip_lst; with Not_found -> match_line simple_skip_lst; in if verbose then prerr_endline ("Line : "^line^" skipped"); (match oc with | None -> () | Some oc -> output_string oc line; output_string oc "\n"); if multiple then skip_aux () with Not_found -> LargeFile.seek_in ic initial_pos with End_of_file -> () in skip_aux () ;;