diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
commit | c853ffb5b2f75f5a889ed2e3ef89b818a736e87a (patch) | |
tree | 7d13a0883bb7936b84d6ecdd7bc332b41ed04bee /src/3rdparty/libcroco | |
parent | Initial commit. (diff) | |
download | inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.tar.xz inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.zip |
Adding upstream version 1.3+ds.upstream/1.3+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/3rdparty/libcroco')
208 files changed, 51467 insertions, 0 deletions
diff --git a/src/3rdparty/libcroco/.clang-format b/src/3rdparty/libcroco/.clang-format new file mode 100644 index 0000000..7612e59 --- /dev/null +++ b/src/3rdparty/libcroco/.clang-format @@ -0,0 +1,16 @@ +BasedOnStyle: LLVM + +AlwaysBreakAfterDefinitionReturnType: All +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +BraceWrapping: + AfterEnum: true + AfterCaseLabel: true + AfterStruct: true + AfterFunction: true + +BinPackParameters: false +ColumnLimit: 80 +IndentWidth: 8 +SpaceAfterCStyleCast: true +SpaceBeforeParens: Always diff --git a/src/3rdparty/libcroco/ABOUT-NLS b/src/3rdparty/libcroco/ABOUT-NLS new file mode 100644 index 0000000..28d38c7 --- /dev/null +++ b/src/3rdparty/libcroco/ABOUT-NLS @@ -0,0 +1,226 @@ +Notes on the Free Translation Project +************************************* + + Free software is going international! The Free Translation Project +is a way to get maintainers of free software, translators, and users all +together, so that will gradually become able to speak many languages. +A few packages already provide translations for their messages. + + If you found this `ABOUT-NLS' file inside a distribution, you may +assume that the distributed package does use GNU `gettext' internally, +itself available at your nearest GNU archive site. But you do *not* +need to install GNU `gettext' prior to configuring, installing or using +this package with messages translated. + + Installers will find here some useful hints. These notes also +explain how users should proceed for getting the programs to use the +available translations. They tell how people wanting to contribute and +work at translations should contact the appropriate team. + + When reporting bugs in the `intl/' directory or bugs which may be +related to internationalization, you should tell about the version of +`gettext' which is used. The information can be found in the +`intl/VERSION' file, in internationalized packages. + +One advise in advance +===================== + + If you want to exploit the full power of internationalization, you +should configure it using + + ./configure --with-included-gettext + +to force usage of internationalizing routines provided within this +package, despite the existence of internationalizing capabilities in the +operating system where this package is being installed. So far, only +the `gettext' implementation in the GNU C library version 2 provides as +many features (such as locale alias or message inheritance) as the +implementation here. It is also not possible to offer this additional +functionality on top of a `catgets' implementation. Future versions of +GNU `gettext' will very likely convey even more functionality. So it +might be a good idea to change to GNU `gettext' as soon as possible. + + So you need not provide this option if you are using GNU libc 2 or +you have installed a recent copy of the GNU gettext package with the +included `libintl'. + +INSTALL Matters +=============== + + Some packages are "localizable" when properly installed; the +programs they contain can be made to speak your own native language. +Most such packages use GNU `gettext'. Other packages have their own +ways to internationalization, predating GNU `gettext'. + + By default, this package will be installed to allow translation of +messages. It will automatically detect whether the system provides +usable `catgets' (if using this is selected by the installer) or +`gettext' functions. If neither is available, the GNU `gettext' own +library will be used. This library is wholly contained within this +package, usually in the `intl/' subdirectory, so prior installation of +the GNU `gettext' package is *not* required. Installers may use +special options at configuration time for changing the default +behaviour. The commands: + + ./configure --with-included-gettext + ./configure --with-catgets + ./configure --disable-nls + +will respectively bypass any pre-existing `catgets' or `gettext' to use +the internationalizing routines provided within this package, enable +the use of the `catgets' functions (if found on the locale system), or +else, *totally* disable translation of messages. + + When you already have GNU `gettext' installed on your system and run +configure without an option for your new package, `configure' will +probably detect the previously built and installed `libintl.a' file and +will decide to use this. This might be not what is desirable. You +should use the more recent version of the GNU `gettext' library. I.e. +if the file `intl/VERSION' shows that the library which comes with this +package is more recent, you should use + + ./configure --with-included-gettext + +to prevent auto-detection. + + By default the configuration process will not test for the `catgets' +function and therefore they will not be used. The reasons are already +given above: the emulation on top of `catgets' cannot provide all the +extensions provided by the GNU `gettext' library. If you nevertheless +want to use the `catgets' functions use + + ./configure --with-catgets + +to enable the test for `catgets' (this causes no harm if `catgets' is +not available on your system). If you really select this option we +would like to hear about the reasons because we cannot think of any +good one ourself. + + Internationalized packages have usually many `po/LL.po' files, where +LL gives an ISO 639 two-letter code identifying the language. Unless +translations have been forbidden at `configure' time by using the +`--disable-nls' switch, all available translations are installed +together with the package. However, the environment variable `LINGUAS' +may be set, prior to configuration, to limit the installed set. +`LINGUAS' should then contain a space separated list of two-letter +codes, stating which languages are allowed. + +Using This Package +================== + + As a user, if your language has been installed for this package, you +only have to set the `LANG' environment variable to the appropriate +ISO 639 `LL' two-letter code prior to using the programs in the +package. For example, let's suppose that you speak German. At the +shell prompt, merely execute `setenv LANG de' (in `csh'), +`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This +can be done from your `.login' or `.profile' file, once and for all. + + An operating system might already offer message localization for +many of its programs, while other programs have been installed locally +with the full capabilities of GNU `gettext'. Just using `gettext' +extended syntax for `LANG' would break proper localization of already +available operating system programs. In this case, users should set +both `LANGUAGE' and `LANG' variables in their environment, as programs +using GNU `gettext' give preference to `LANGUAGE'. For example, some +Swedish users would rather read translations in German than English for +when Swedish is not available. This is easily accomplished by setting +`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'. + +Translating Teams +================= + + For the Free Translation Project to be a success, we need interested +people who like their own language and write it well, and who are also +able to synergize with other translators speaking the same language. +Each translation team has its own mailing list, courtesy of Linux +International. You may reach your translation team at the address +`LL@li.org', replacing LL by the two-letter ISO 639 code for your +language. Language codes are *not* the same as the country codes given +in ISO 3166. The following translation teams exist, as of December +1997: + + Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en', + Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian + `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja', + Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish + `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es', + Swedish `sv', and Turkish `tr'. + +For example, you may reach the Chinese translation team by writing to +`zh@li.org'. + + If you'd like to volunteer to *work* at translating messages, you +should become a member of the translating team for your own language. +The subscribing address is *not* the same as the list itself, it has +`-request' appended. For example, speakers of Swedish can send a +message to `sv-request@li.org', having this message body: + + subscribe + + Keep in mind that team members are expected to participate +*actively* in translations, or at solving translational difficulties, +rather than merely lurking around. If your team does not exist yet and +you want to start one, or if you are unsure about what to do or how to +get started, please write to `translation@iro.umontreal.ca' to reach the +coordinator for all translator teams. + + The English team is special. It works at improving and uniformizing +the terminology in use. Proven linguistic skill are praised more than +programming skill, here. + +Available Packages +================== + + Languages are not equally supported in all packages. The following +matrix shows the current state of internationalization, as of December +1997. The matrix shows, in regard of each package, for which languages +PO files have been submitted to translation coordination. + + Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv + .----------------------------------------------------. + bash | [] [] [] | 3 + bison | [] [] [] | 3 + clisp | [] [] [] [] | 4 + cpio | [] [] [] [] [] [] | 6 + diffutils | [] [] [] [] [] | 5 + enscript | [] [] [] [] [] [] | 6 + fileutils | [] [] [] [] [] [] [] [] [] [] | 10 + findutils | [] [] [] [] [] [] [] [] [] | 9 + flex | [] [] [] [] | 4 + gcal | [] [] [] [] [] | 5 + gettext | [] [] [] [] [] [] [] [] [] [] [] | 12 + grep | [] [] [] [] [] [] [] [] [] [] | 10 + hello | [] [] [] [] [] [] [] [] [] [] [] | 11 + id-utils | [] [] [] | 3 + indent | [] [] [] [] [] | 5 + libc | [] [] [] [] [] [] [] | 7 + m4 | [] [] [] [] [] [] | 6 + make | [] [] [] [] [] [] | 6 + music | [] [] | 2 + ptx | [] [] [] [] [] [] [] [] | 8 + recode | [] [] [] [] [] [] [] [] [] | 9 + sh-utils | [] [] [] [] [] [] [] [] | 8 + sharutils | [] [] [] [] [] [] | 6 + tar | [] [] [] [] [] [] [] [] [] [] [] | 11 + texinfo | [] [] [] | 3 + textutils | [] [] [] [] [] [] [] [] [] | 9 + wdiff | [] [] [] [] [] [] [] [] | 8 + `----------------------------------------------------' + 17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv + 27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179 + + Some counters in the preceding matrix are higher than the number of +visible blocks let us expect. This is because a few extra PO files are +used for implementing regional variants of languages, or language +dialects. + + For a PO file in the matrix above to be effective, the package to +which it applies should also have been internationalized and +distributed as such by its maintainer. There might be an observable +lag between the mere existence a PO file and its wide availability in a +distribution. + + If December 1997 seems to be old, you may fetch a more recent copy +of this `ABOUT-NLS' file on most GNU archive sites. + diff --git a/src/3rdparty/libcroco/AUTHORS b/src/3rdparty/libcroco/AUTHORS new file mode 100644 index 0000000..75562c3 --- /dev/null +++ b/src/3rdparty/libcroco/AUTHORS @@ -0,0 +1,13 @@ +Dodji Seketeli <dodji@gnome.org> +----------------------------------- +Initial Author, main maintainer and main architect. + +Gael Chamoulaud <strider@gnome.org> +########################################## +Programmer. + +Rob BUIS <rwlbuis@xs4all.nl> +---------------------------- +Sent several patches. + + diff --git a/src/3rdparty/libcroco/CMakeLists.txt b/src/3rdparty/libcroco/CMakeLists.txt new file mode 100644 index 0000000..d3e0366 --- /dev/null +++ b/src/3rdparty/libcroco/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.6) + +project(libcroco LANGUAGES C) + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(LIBCROCO_STANDALONE TRUE) +endif() + +set(LIBCROCO_MAJOR_VERSION 0) +set(LIBCROCO_MINOR_VERSION 6) +set(LIBCROCO_MICRO_VERSION 99) +set(LIBCROCO_VERSION ${LIBCROCO_MAJOR_VERSION}.${LIBCROCO_MINOR_VERSION}.${LIBCROCO_MICRO_VERSION}) +math(EXPR LIBCROCO_VERSION_NUMBER "${LIBCROCO_MAJOR_VERSION} * 10000 + + ${LIBCROCO_MINOR_VERSION} * 100 + + ${LIBCROCO_MICRO_VERSION}") + +find_package(PkgConfig REQUIRED) + +set(GLIB_REQUIRED 2.0) +set(LIBXML_REQUIRED 2.4.23) + +pkg_check_modules(GLIB REQUIRED glib-2.0>=${GLIB_REQUIRED}) +pkg_check_modules(LIBXML REQUIRED libxml-2.0>=${LIBXML_REQUIRED}) + +add_subdirectory(src) + +option(LIBCROCO_TESTING "Build tests" "${LIBCROCO_STANDALONE}") + +if (LIBCROCO_TESTING) + enable_testing() + add_subdirectory(csslint) + add_subdirectory(tests) +endif() diff --git a/src/3rdparty/libcroco/CODING-STYLE b/src/3rdparty/libcroco/CODING-STYLE new file mode 100644 index 0000000..1e76519 --- /dev/null +++ b/src/3rdparty/libcroco/CODING-STYLE @@ -0,0 +1,113 @@ +Author: Dodji Seketeli.
+-----------------------
+
+Introduction
+------------
+
+The coding standard we use are based on the GNU coding standards
+available at http://www.gnu.org/prep/standards_toc.html
+and on the Gnome Coding standards available at
+http://developer.gnome.org/doc/guides/programming-guidelines/book1.html .
+
+Please, make sure you read these documents before you read this one.
+
+I) General coding style rules
+---------------------------
+
+Coding style refers to the way the code is formatted.
+Here are the guidelines we use in this project:
+
+Indentation Style
+- - - - - - - - - -
+
+We use the 2-spaces tab indentation style (the GNU's one) .
+
+Make sure as much as possible that each code line does not
+exceed 80 characters length. Why ? because you don't know
+who will read your code. The smallest screens are 80 chars
+wide. So, please, make the code available to everybody.
+
+
+Functions naming
+- - - - - - - -
+
+We use the GNU name scheme to name our functions.
+
+GOOD:
+
+int
+my_function_name (char a_variable_name)
+{
+ printf ("The variable value is %c", a_variable_name) ;
+ return 0 ;
+}
+
+
+BAD:
+
+int
+myFunctionName (char blabla)
+{
+ printf ("This is awfull\n") ;
+}
+
+or
+
+int my_FunctionName (char Blabla) {
+ printf ("This is bad\n") ;
+}
+
+The words of the function names are separared by an underscore ('_') and
+are written in lower case.
+The name functions arguments always start with by a "a_" .
+
+Avoid for instance the Java function (method) name scheme by mixing
+upper and lower case in the function names.
+
+
+Be genereous with white spaces:
+
+GOOD:
+
+int foo (int a_parameter)
+{
+ if (test == TRUE) {
+ printf ("Coucou\n") ;
+ }
+}
+
+BAD:
+
+int foo(int a_parameter)
+{
+ if(test==TRUE) {
+ printf("coucou\n")
+ }
+}
+
+
+To ensure that the each line of code is less than 80 characters,
+if a function has many parameters, you can write it this way:
+
+
+Constants naming
+- - - - - - - - -
+Constants (defines or constant variables) must be in upper case.
+The worlds of the constant name must be separated by an underscore ('_').
+For instance:
+
+GOOD:
+gint A_CONSTANT = 10 ;
+#define ANOTHER_CONSTANT 100 ;
+
+BAD:
+gin a_Constant = 10 ;
+#define another_Constant ;
+
+
+structure and enum naming
+---------------------
+
+
+II) Object Oriented C programming
+-----------------------------
diff --git a/src/3rdparty/libcroco/COPYING b/src/3rdparty/libcroco/COPYING new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/src/3rdparty/libcroco/COPYING @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU 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., 675 Mass Ave, Cambridge, MA 02139, 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. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/3rdparty/libcroco/COPYING.LIB b/src/3rdparty/libcroco/COPYING.LIB new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/src/3rdparty/libcroco/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, 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. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU 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., 675 Mass Ave, Cambridge, MA 02139, 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. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/3rdparty/libcroco/COPYRIGHTS b/src/3rdparty/libcroco/COPYRIGHTS new file mode 100644 index 0000000..fa33102 --- /dev/null +++ b/src/3rdparty/libcroco/COPYRIGHTS @@ -0,0 +1,4 @@ +Except where otherwise noted in the source code all the files are: + + Copyright (C) 2003-2004 Dodji Seketeli. All Rights Reserved. + diff --git a/src/3rdparty/libcroco/Doxyfile b/src/3rdparty/libcroco/Doxyfile new file mode 100644 index 0000000..0c210a3 --- /dev/null +++ b/src/3rdparty/libcroco/Doxyfile @@ -0,0 +1,946 @@ +# Doxyfile 1.2.16 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Libcroco + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs/apis + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Korean, +# Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovene, +# Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line and do not end with a semicolon. Such function macros are typically +# used for boiler-plate code, and will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/src/3rdparty/libcroco/Makefile.am b/src/3rdparty/libcroco/Makefile.am new file mode 100644 index 0000000..4b482f3 --- /dev/null +++ b/src/3rdparty/libcroco/Makefile.am @@ -0,0 +1,72 @@ +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc + +SUBDIRS = src csslint docs tests win32 + +PKG_CONFIG_FILE_UNINSTALLED=libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-uninstalled.pc +PKG_CONFIG_FILE=libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@.pc + +pkgconfigdir=$(libdir)/pkgconfig +pkgconfig_DATA=$(PKG_CONFIG_FILE) + +INCLUDE_DIR_NAME=@PACKAGE@-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ +extraincludedir=$(includedir)/$INCLUDE_DIR_NAME + +CROCO_CONFIG_FILE_UNINSTALLED=croco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-config-uninstalled +CROCO_CONFIG_FILE=croco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-config +bin_SCRIPTS=$(CROCO_CONFIG_FILE) + +#man_MANS = croco-config.1 + +EXTRA_DIST= croco-config.in $(PKG_CONFIG_FILE) TODO Doxyfile \ +HACKING COPYING.LIB COPYING libcroco.spec libcroco-zip.in \ +autogen.sh libcroco.doap config.h.win32.in config.h.win32 + +all-local: $(PKG_CONFIG_FILE_UNINSTALLED) $(PKG_CONFIG_FILE) \ +$(CROCO_CONFIG_FILE_UNINSTALLED) $(CROCO_CONFIG_FILE) + + +%-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@.pc: %.pc + cp $< $@ + +%-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-uninstalled.pc: %.pc + cp $< $@ + +%-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-config: %-config + cp $< $@ + +%-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-config-uninstalled: %-config + cp $< $@ + +clean-local: cleantest +distclean-local: + -rm ./croco-0.6-config ./libcroco-0.6.pc ./libcroco-0.6-uninstalled.pc ./croco-0.6-config-uninstalled + +cleantest: + if test -x $(top_srcdir)/tests/testctl ; then $(top_srcdir)/tests/testctl cleanup ; fi + +cleantar: + @(rm -f libcroco*.tar.gz) + @(rm -rf $(top_srcdir)/rpmbuildroot) + +rpm: cleantar + @(mkdir -p $(top_srcdir)/rpmbuildroot ; $(MAKE) dist && rpmbuild -ta --buildroot $(top_srcdir)/rpmbuildroot $(distdir).tar.gz) + +test: all + if test -x $(top_srcdir)/tests/testctl ; then $(top_srcdir)/tests/testctl cleanup ; $(top_srcdir)/tests/testctl run ; fi + +apidoc: + if ! test -d docs/apis ; then mkdir -p docs/apis ; fi ; + doxygen Doxyfile + +ChangeLog: + $(AM_V_GEN) if test -f $(top_srcdir)/.git/HEAD; then \ + git log --stat > $@; \ + fi + +dist: ChangeLog + +.PHONY: ChangeLog + + diff --git a/src/3rdparty/libcroco/NEWS b/src/3rdparty/libcroco/NEWS new file mode 100644 index 0000000..a74ee44 --- /dev/null +++ b/src/3rdparty/libcroco/NEWS @@ -0,0 +1,178 @@ +0.6.99 + * Apply inkscape modifications + * Consider significant digits for number formatting + * Use single instead of double quotes for string output + * cr_cascade_set_sheet: Allow a_sheet=NULL + * cr_stylesheet_new: Fix reference counting + * Mem leak fixes + +0.6.13 + * Visual Studio builds: Enhance security of x64 binaries + * win32/replace.py: Fix replacing items in files with UTF-8 content + * tknzr: support only max long rgb values + * input: check end of input before reading a byte + +0.6.12 + * Add support for Visual Studio 2017 (Chun-wei Fan) + * Misc bug fixes + +0.6.11 + * Fix regression in cr_tknzr_consume_chars (Florian Müllner) + * Misc bug fixes + +0.6.10 + * Misc bug fixes + +0.6.9 + * Added Visual Studio projects (Chun-wei Fan) + * Lots of warnings fixed (Руслан Ижбулатов) + * Improve build system (Nuno Araujo, Ignacio Casal Quinteiro) + * Misc bug fixes + +0.6.8 + * Handle signed units (Jasper St. Pierre, #686239) + +0.6.6.6 + * Fix 'green' colour (#685679) + * Build fixes + +0.6.6 + * Mem leak fixes (#678736) + +0.6.5 + + Changes & Bugfixes since 0.6.4 + ============================== + * Fix mapping of 'green' colour (#672332) + +0.6.4 + + Changes & Bugfixes since 0.6.3 + ============================== + * Use -Bsymbolic-functions when available + * Modernise and simplify configure + * #666248: vc++ compilation support + * #640897: fix format string warning in testcase + +0.6.3: + + Bugfixes since 0.6.2 + ==================== + - #342370: ensure the library and compiler flags are not hardcoded into the pc file + - add gtk-doc build infrastructure + +0.6.2: February 4, 2009 + + Bugfixes since 0.6.1 + ==================== + + - #306823: improve precision of non-integer numbers [Peter Moulder] + - #148790, #333834: Cygwin fixes + - #340298: Documentation fixes [Peter Moulder] + - #375194: fix to builtin color processing [Dom Lachowicz] + - #380438: Leak and trace message in cr_token_clear [Mark Rogers] + - #381040: floating numbers always output to exactly 3 digits after + decimal points [Dom Lachowicz] + - #336621: cr_tknzr_get_next_token wasn't handling "<!--" correctly + - #372011: comments not parsed correctly [Benjamin Dauvergne] + - #394680: problem parsing function name starting with 'u' or 'r' + [Benjamin Dauvergne] + - #139878: keep end of ruleset parsing location, and give it to the + end_selector sac-handler. [Benjamin Dauvergne] + - #394294: Escape are wrongly computed [Benjamin Dauvergne] + - #314831: Escapes not recognized [Benjamin Dauvergne] + - #395099: overly aggressive rule matching [Bruno Haible] + - #553937: CRDocHandler instances created with reference count of 0 + [Robert Staudinger] + + - Various fixes to the font handling [Bruno Haible] + - Add ‘const’ to various function prototypes [Peter Moulder] + + +0.6.1: March 5, 2006 + + Bugfixes since 0.6.0 + ==================== + + - parse fractional parts of numbers properly [Dom Lachowicz] + - win32 port [Tor Lillqvist] + - gtk-doc compliance [Sven Herzberg] + - test infrastructure enhancements [Peter Moulder] + - nasty memory management bug fix [ArjanV, Daniel Veillard] + +0.6.0: June 9, 2004 + + Enhancements since 0.5.1 + ======================== + + - add parsing location to all the CSS constructions at SAC level [Dodji Seketeli] + - add --dump-location option to csslint [Dodji Seketeli] + - enable several API/ABI incompatible versions of Libcroco to be + installed on the same box [Dodji Seketeli] + - CSS properties inheritance support [Benjamin Dauvergne] + - CRStyle struct gatehering code cleanup [Benjamin Dauvergne] + - Better support for font selection [Dodji Seketeli] + + Bugfixes since 0.5.1 + ====================== + + - #143308: fix parsing of non trivial functional #notations. [Dodji Seketeli] + - #143450: fix gcc 2.xx errors. [Dodji Seketeli] + - #139881: proper setting of parsing locations in urls. [Dodji Seketeli] + - #138267: remove C99-isms. + - #139889: fix an infinite loop in the parser [Dodji Seketeli] + - #139891: better @media rule reporting [Dodji Seketeli] + - #140317: fix class sel without class name crash [Dodji Seketeli] + - #140334: fix an infinite loop in the parser [Dodji Seketeli] + - attribute selectors evaluation fixes. [Dodji Seketeli] + - Better support of descendant selectors evaluation [Dodji Seketeli] + - Better regression tests framework [Dodji Seketeli] + +0.5.1: April 18 2004: + + - fixes: #140334, #140317, #139891, #139615. [Dodji Seketeli] + +0.5: March 16 2004: + + - better regression suite framework [Dodji Seketeli] + - support of the 'color' property gathering [Benjamin Dauvergne] + - furious memory leaks/corruptions hunting [Dodji Seketeli, Rob BUIS] + - total support of the !important keyword [Dodji Seketeli, Rob BUIS] + - selectors evaluation in csslint [Dodji Seketeli, Rob BUIS] + - fix compilation warnings [David A Knight, Dodji Seketeli] + - more complete CSS statement serialisation [Dodji Seketeli] + - better gathering of style information [Dodjij Seketeli] + - better cascading algorithm conformance [Dodji Seketeli, Rob BUIS] + - @import rule parsing fix [Dodji Seketeli] + - support of CSS3 indentifiers [Dodji Seketeli] + - better w3c DOM integration support [Rob BUIS, Dodji Seketeli] + - many parsing fixes [Dodji Seketeli] + - style structure debugging facility [Dodji Seketeli] + - better fragment parsing support [Dodji Seketeli] + - Split libcroco and sewfox [Dodji Seketeli] + - class selector evaluation fix [Rob BUIS] + - csslint cleanup and bugfixes [Dodji Seketeli] + - :first-child pseudo class selector support [Dodji Seketeli] + - pluggable pseudo class selectors evaluators [Dodji Seketeli] + + +libcroco 0.2.0 + 2003 Jun 29 + libcroco 0.2.0 ChangeLog: + * Went forward in the layout engine. Can now render + simple xml element along with simple CSS sheets. + Supported layout is normal layout for box and inline + context. + * Cleaned up the parsing api. Fixed a lot of bugs. + * Added some new api calls to the parsing api. + * See the ChangeLog shipped within the tarball for + more precise descriptions. + +libcroco 0.1.0 + + 2003 Mar 19 + With the approval off all contributors the library has been + relicensed from GPL -> LGPL + +------------------------------------------------------------------------------ + diff --git a/src/3rdparty/libcroco/README.md b/src/3rdparty/libcroco/README.md new file mode 100644 index 0000000..d7aa48e --- /dev/null +++ b/src/3rdparty/libcroco/README.md @@ -0,0 +1,15 @@ +[![build status](https://gitlab.com/inkscape/libcroco/badges/master/pipeline.svg)](https://gitlab.com/inkscape/libcroco/-/pipelines) + +What is The Croco Project ? +------------------------------ + +Libcroco is a standalone css2 parsing and manipulation library. +The parser provides a low level event driven SAC like api +and a css object model like api. +Libcroco provides a CSS2 selection engine and an experimental +xml/css rendering engine. + +This is a fork of the original +[Gnome libcroco](https://gitlab.gnome.org/Archive/libcroco) +project, which was discontinued. It's sole purpose is to be used with +[Inkscape](https://gitlab.com/inkscape/inkscape).
\ No newline at end of file diff --git a/src/3rdparty/libcroco/TODO b/src/3rdparty/libcroco/TODO new file mode 100644 index 0000000..d0062d6 --- /dev/null +++ b/src/3rdparty/libcroco/TODO @@ -0,0 +1,45 @@ + +*coding:) + + + +Well, in the cr_statement_xxx_parse_functions, memleaks +occur (the parsing result set in the sac callback is not freed) +when a parsing fails. This is because the unrecoverable error +does not get called when the standalone parsing functions exported +by CRParser are called independently. +I have now to support 2 modes of parsing. Normal and standalone. +In standalone mode, the standalone parsing functions must +call the "unrecoverable_error" sac callback when they fail. + +implements the width:20% case. (on going) + implement the size wrapping using the rightmost_x field of CRLayEngPriv. + +Provide support for font selection. (hard, started, is well underway.) + First make sure to be able to gather all the font related property + values. + Then, figure out how to implement a font selector that uses + pango. (on going) + +Go forward in the cascading implementation in cr-sel-eng.c + test/debug it. + write test cases to test/debug/validate this kind of stylesheets: + P {border: thick} + P {display: block} + /* + *stylesheets where the same selector is used several times + *to define different declarations. + */ + write test cases to test/debug/validate the multi stylesheet support. + + +*Doc:) + +Write examples of how to use the SAC api of libcroco and how to +walk the css stylesheet tree. + +Finish the design of the instruction set of the selection engine. + The draft design is in the file + docs/designs/docs/design/sel-instr.txt. + +Write a little doc about how to use the parser as it is today. diff --git a/src/3rdparty/libcroco/acinclude.m4 b/src/3rdparty/libcroco/acinclude.m4 new file mode 100644 index 0000000..cc65b75 --- /dev/null +++ b/src/3rdparty/libcroco/acinclude.m4 @@ -0,0 +1,319 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com> +dnl Copyright (c) 2006-2008 xine project +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if the flag is supported by compiler +dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ + AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], + [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl Check if the flag is supported by compiler (cacheable) +dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) +dnl Check for CFLAG and appends them to CFLAGS if supported +AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) +]) + +dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) +AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ + for flag in $1; do + CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) + done +]) + +dnl Check if the flag is supported by linker (cacheable) +dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LANG_PUSH([C]) + AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + AC_LANG_POP([C]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for +dnl the current linker to avoid undefined references in a shared object. +AC_DEFUN([CC_NOUNDEFINED], [ + dnl We check $host for which systems to enable this for. + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host in + dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads + dnl are requested, as different implementations are present; to avoid problems + dnl use -Wl,-z,defs only for those platform not behaving this way. + *-freebsd* | *-openbsd*) ;; + *) + dnl First of all check for the --no-undefined variant of GNU ld. This allows + dnl for a much more readable commandline, so that people can understand what + dnl it does without going to look for what the heck -z defs does. + for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break + done + ;; + esac + + AC_SUBST([LDFLAGS_NOUNDEFINED]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }])], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/src/3rdparty/libcroco/autogen.sh b/src/3rdparty/libcroco/autogen.sh new file mode 100755 index 0000000..8a7d049 --- /dev/null +++ b/src/3rdparty/libcroco/autogen.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. + +olddir=`pwd` + +cd $srcdir + +(test -f configure.ac) || { + echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***" + exit 1 +} + +PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac` + +if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then + echo "*** WARNING: I am going to run \`configure' with no arguments." >&2 + echo "*** If you wish to pass any to it, please specify them on the" >&2 + echo "*** \`$0\' command line." >&2 + echo "" >&2 +fi + +aclocal --install || exit 1 +gtkdocize --copy || exit 1 +autoreconf --verbose --force --install -Wno-portability || exit 1 + +cd $olddir +if [ "$NOCONFIGURE" = "" ]; then + $srcdir/configure "$@" || exit 1 + + if [ "$1" = "--help" ]; then exit 0 else + echo "Now type \`make\' to compile $PKG_NAME" || exit 1 + fi +else + echo "Skipping configure process." +fi diff --git a/src/3rdparty/libcroco/config.h.win32.in b/src/3rdparty/libcroco/config.h.win32.in new file mode 100644 index 0000000..63d5c09 --- /dev/null +++ b/src/3rdparty/libcroco/config.h.win32.in @@ -0,0 +1,99 @@ +/* config.h.in. Handwritten for Windows compilation with MSVC. */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Fan, Chun-wei + * See COPYRIGHTS file for copyright information. + */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +/*#undef HAVE_DLFCN_H*/ + +/* Define to 1 if you have the <inttypes.h> header file. */ +#ifndef _MSC_VER +#define HAVE_INTTYPES_H 1 +#endif + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#if (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +#define HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#ifndef _MSC_VER +#define HAVE_STRINGS_H 1 +#endif + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#ifndef _MSC_VER +#define HAVE_UNISTD_H 1 +#endif + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libcroco" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=libcroco" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libcroco" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libcroco @LIBCROCO_VERSION@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libcroco" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@LIBCROCO_VERSION@" + +/* Define to 1 if the C compiler supports function prototypes. */ +#define PROTOTYPES 1 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "@LIBCROCO_VERSION@" + +/* Define like PROTOTYPES; this can be used by system headers. */ +#define __PROTOTYPES 1 diff --git a/src/3rdparty/libcroco/configure.ac b/src/3rdparty/libcroco/configure.ac new file mode 100644 index 0000000..59aa072 --- /dev/null +++ b/src/3rdparty/libcroco/configure.ac @@ -0,0 +1,191 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.64) +AC_INIT([libcroco],[0.6.99],[https://gitlab.com/inkscape/libcroco/-/issues],[libcroco]) +AC_CONFIG_SRCDIR([src/cr-input.c]) +AC_CANONICAL_HOST + +# gnu strictness to generate the INSTALL file +AM_INIT_AUTOMAKE([1.13 tar-ustar dist-xz no-dist-gzip -Wno-portability foreign]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +if test -z "$enable_maintainer_mode"; then + enable_maintainer_mode=yes +fi +AM_MAINTAINER_MODE([enable]) + +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) + +LIBCROCO_MAJOR_VERSION=0 +LIBCROCO_MINOR_VERSION=6 +LIBCROCO_MICRO_VERSION=99 + +LIBCROCO_CURRENT=3 +LIBCROCO_REVISION=1 +LIBCROCO_AGE=0 + +#LIBCROCO_VERSION_INFO=`expr $LIBCROCO_MAJOR_VERSION + $LIBCROCO_MINOR_VERSION`:$LIBCROCO_MICRO_VERSION:$LIBCROCO_MINOR_VERSION +LIBCROCO_VERSION_INFO="$LIBCROCO_CURRENT:$LIBCROCO_REVISION:$LIBCROCO_AGE" +LIBCROCO_VERSION=$LIBCROCO_MAJOR_VERSION.$LIBCROCO_MINOR_VERSION.$LIBCROCO_MICRO_VERSION +LIBCROCO_VERSION_NUMBER=`expr $LIBCROCO_MAJOR_VERSION \* 10000 + $LIBCROCO_MINOR_VERSION \* 100 + $LIBCROCO_MICRO_VERSION` + +AC_SUBST(LIBCROCO_MAJOR_VERSION) +AC_SUBST(LIBCROCO_MINOR_VERSION) +AC_SUBST(LIBCROCO_MICRO_VERSION) +AC_SUBST(LIBCROCO_VERSION) +AC_SUBST(LIBCROCO_VERSION_INFO) +AC_SUBST(LIBCROCO_VERSION_NUMBER) +AC_SUBST(LIBCROCO_CURRENT) +AC_SUBST(LIBCROCO_AGE) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_CPP +AC_PROG_MAKE_SET +AC_STDC_HEADERS +AC_ISC_POSIX + +LT_INIT([]) + +CROCO_LIB=libcroco-$LIBCROCO_MAJOR_VERSION.$LIBCROCO_MINOR_VERSION.la +AC_SUBST(CROCO_LIB) + +case "$host" in + *-*-cygwin*|*-*-mingw*) + platform_win32=yes + ;; + *) + platform_win32=no + ;; +esac +AM_CONDITIONAL(PLATFORM_WIN32, [test "$platform_win32" = "yes"]) + +GTK_DOC_CHECK([1.0]) + +dnl ************************************************************** +dnl check for the different --enable-option=val +dnl messages issued by the user +dnl *************************************************************** +G_DISABLE_CHECKS=0 +AC_ARG_ENABLE(checks, + AC_HELP_STRING([--enable-checks=yes|no], + [enables runtime safety checks. Default=yes]), + WITH_CHECKS=$enableval, + WITH_CHECKS="yes") + +if test "$WITH_CHECKS" = "no" ; then + G_DISABLE_CHECKS=1 +fi +AC_SUBST(G_DISABLE_CHECKS) + +dnl ************************************************ +dnl end of check of the different --enable-feature options +dnl ************************************************* + +############## +# Dependencies +############## + +GLIB_REQUIRED=2.0 +LIBXML_REQUIRED=2.4.23 + +PKG_CHECK_MODULES([CROCO],[ + glib-2.0 >= $GLIB_REQUIRED + libxml-2.0 >= $LIBXML_REQUIRED]) + +########################################################## +# Check for -Bsymbolic-functions linker flag used to avoid +# intra-library PLT jumps, if available. +########################################################## + +AC_ARG_ENABLE([Bsymbolic], + [AS_HELP_STRING([--disable-Bsymbolic], + [disable linking with -Bsymbolic])], + [],[enable_Bsymbolic=yes]) + +BSYMBOLIC_LDFLAG= +if test "$enable_Bsymbolic" != "no"; then + CC_CHECK_LDFLAGS(["-Wl,-Bsymbolic-functions"], + [BSYMBOLIC_LDFLAG="-Wl,-Bsymbolic-functions"], + [if test "$enable_Bsymbolic" = "auto"; then + AC_MSG_WARN([-Bsymbolic not supported by ld; disabling]) + enable_Bsymbolic=no + else + AC_MSG_ERROR([-Bsymbolic requested but not supported by ld. Use --disable-Bsymbolic to disable]) + fi]) +fi + +AC_SUBST([BSYMBOLIC_LDFLAG]) + +############################################## +# Check whether MSVC toolset is explicitly set +############################################## + +AM_CONDITIONAL(MSVC_BASE_NO_TOOLSET_SET, [test x$MSVC_BASE_TOOLSET = x]) +AM_CONDITIONAL(MSVC_NO_TOOLSET_SET, [test x$MSVC_TOOLSET = x]) + +################### +# Compiler warnings +################### + +CC_CHECK_CFLAGS_APPEND([ \ + -Wall -Wextra \ + -Wunused -Wreturn-type -Wswitch -Wcomment -Wtrigraphs \ + -Wchar-subscripts -Wparentheses -Winline -Wredundant-decls \ + -Wformat-nonliteral -Werror=format-security \ + -Wsign-compare -Werror=implicit-function-declaration \ + -Wpointer-arith -Wwrite-strings -Wstrict-prototypes \ + -Wcast-align -Wimplicit -Wuninitialized \ + -Wmissing-prototypes -Wmissing-declarations -Wnested-externs \ + -Wpacked -Wmissing-format-attribute -Wshadow \ + -Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \ + -Wdeclaration-after-statement -Wold-style-definition \ + -Wno-missing-field-initializers -Wno-unused-parameter \ + -fno-common -Wno-switch-enum]) + +########################################## + +AC_OUTPUT([ +Makefile +libcroco.pc +libcroco.spec +libcroco-zip +croco-config +config.h.win32 +win32/Makefile +win32/vs9/Makefile +win32/vs9/croco-version-paths.vsprops +win32/vs10/Makefile +win32/vs10/croco-version-paths.props +win32/vs11/Makefile +win32/vs12/Makefile +win32/vs14/Makefile +win32/vs15/Makefile +win32/vs16/Makefile +docs/Makefile +docs/examples/Makefile +docs/reference/Makefile +tests/Makefile +tests/test-inputs/Makefile +tests/test-output-refs/Makefile +global-test-vars.sh +src/Makefile +src/libcroco-config.h +csslint/Makefile + +]) + +dnl ======================================================================= +echo " + ===================================================================== + LIBCROCO, GNOME CSS2 PARSING AND MANIPULATION TOOLKIT $VERSION + ===================================================================== + + prefix: : ${prefix} + source code location: : ${srcdir} + compiler: : ${CC} + cflags: : ${CFLAGS} + + Maintainer mode: : ${USE_MAINTAINER_MODE} +" diff --git a/src/3rdparty/libcroco/croco-config.1 b/src/3rdparty/libcroco/croco-config.1 new file mode 100644 index 0000000..9418e72 --- /dev/null +++ b/src/3rdparty/libcroco/croco-config.1 @@ -0,0 +1,37 @@ +.TH LIBCROCO 1 "20 January 2003" Version 0.1.0 +.SH NAME +croco-config - script to get information about the installed version of LIBCROCO +.SH SYNOPSIS +.B croco-config +[\-\-prefix\fI[=DIR]\fP] [\-\-libs] [\-\-cflags] [\-\-version] [\-\-help] +.SH DESCRIPTION +\fIcroco-config\fP is a tool used to determine the necessary flags to compile and +link programs that uses \fILIBCROCO\fP. +.SH OPTIONS +.l +\fIcroco-config\fP accepts the following options: +.TP 8 +.B \-\-version +Print the currently installed version of \fILIBCROCO\fP on the standard output. +.TP 8 +.B \-\-libs +Print the linker flags necessary to link a \fILIBCROCO\fP program. +.TP 8 +.B \-\-cflags +Print the compiler flags necessary to compile a \fILIBCROCO\fP program. +.TP 8 +.B \-\-prefix=PREFIX +If specified, use PREFIX instead of the installation prefix that +\fILIBCROCO\fP was built with when computing the output for the +\-\-cflags and \-\-libs options. This option must be specified before +any \-\-libs or \-\-cflags options. +.SH AUTHOR +This manual page was written by Gael CHAMOULAUD (strider) <strider@freespiders.org> +.SH REPORTING BUGS +Please report bugs at http://bugzilla.gnome.org. +.SH COPYRIGHT +Copyright (C) 2002-2003 Dodji SEKETELI, Gael CHAMOULAUD. +.br +This is a free software; see the source for copying conditions. There is +NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. diff --git a/src/3rdparty/libcroco/croco-config.in b/src/3rdparty/libcroco/croco-config.in new file mode 100644 index 0000000..36ef10a --- /dev/null +++ b/src/3rdparty/libcroco/croco-config.in @@ -0,0 +1,82 @@ +#! /bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage() +{ + cat <<EOF +Usage: croco-config [OPTION]... + +Known values for OPTION are: + + --prefix=DIR change CROCO prefix [default $prefix] + --exec-prefix=DIR change CROCO executable prefix [default $exec_prefix] + --libs print library linking information + --cflags print pre-processor and compiler flags + --help display this help and exit + --version output version information +EOF + + exit $1 +} + +if test $# -eq 0; then + usage 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case "$1" in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + + --prefix) + echo $prefix + ;; + + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + + --exec-prefix) + echo $exec_prefix + ;; + + --version) + echo @VERSION@ + exit 0 + ;; + + --help) + usage 0 + ;; + + --cflags) + echo @CROCO_CFLAGS@ @GLIB2_CFLAGS@ @LIBXML2_CFLAGS@ + ;; + + --libs) + echo @CROCO_LIBS@ @GLIB2_LIBS@ @LIBXML2_LIBS@ + ;; + + *) + usage + exit 1 + ;; + esac + shift +done + + +exit 0 diff --git a/src/3rdparty/libcroco/csslint/CMakeLists.txt b/src/3rdparty/libcroco/csslint/CMakeLists.txt new file mode 100644 index 0000000..8f125c8 --- /dev/null +++ b/src/3rdparty/libcroco/csslint/CMakeLists.txt @@ -0,0 +1,16 @@ +set(csslint_EXE csslint) + +add_executable(${csslint_EXE} csslint.c) + +target_include_directories(${csslint_EXE} + PRIVATE + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src + ${GLIB_INCLUDE_DIRS} + ${LIBXML_INCLUDE_DIRS} +) + +target_link_libraries(${csslint_EXE} + PRIVATE + croco_LIB +) diff --git a/src/3rdparty/libcroco/csslint/ChangeLog b/src/3rdparty/libcroco/csslint/ChangeLog new file mode 100644 index 0000000..b7b1df6 --- /dev/null +++ b/src/3rdparty/libcroco/csslint/ChangeLog @@ -0,0 +1,29 @@ +2004-01-27 Gael CHAMOULAUD <strider@gnome.org> + + * csslint/csslint.c: (csslint_show_version): Made smallish cleanup + +2003-06-28 Gal Chamoulaud <strider@freespiders.org> + + * csslint.c (csslint_show_version): Added CROCO_LAYENG_ENABLED test + in csslint_show_version function. + +2003-04-02 Gal Chamoulaud <strider@freespiders.org> + + * csslint.1: updated man page + +2003-03-24 Gal Chamoulaud <strider@freespiders.org> + + * csslint.c (csslint_usage): Added the ability to parse + a CSS file and builds a CSS object model. + * csslint.1: updated csslint man page + + +2003-03-23 Gal Chamoulaud <strider@freespiders.org> + + * Makefile.am (AM_CFLAGS): added a man page for csslint program. + + * csslint.1: added a man page for csslint program. + + * csslint.c: initialized the csslint program. A command CSS + parser tool for LIBCRCCO. + diff --git a/src/3rdparty/libcroco/csslint/Makefile.am b/src/3rdparty/libcroco/csslint/Makefile.am new file mode 100644 index 0000000..3969962 --- /dev/null +++ b/src/3rdparty/libcroco/csslint/Makefile.am @@ -0,0 +1,18 @@ +bin_PROGRAMS = csslint-0.6 +#man_MANS = csslint.1 + +csslint_0_6_SOURCES = csslint.c + +croco_lib = $(top_builddir)/src/@CROCO_LIB@ + +csslint_0_6_LDADD = $(croco_lib) + +csslint_0_6_CPPFLAGS = \ + -I$(top_srcdir)/intl \ + -I$(top_srcdir)/src \ + -I$(top_builddir)/src \ + $(CROCO_CFLAGS) + +csslint_0_6_LDFLAGS=$(CROCO_LIBS) + +#EXTRA_DIST = $(man_MANS) diff --git a/src/3rdparty/libcroco/csslint/csslint.1 b/src/3rdparty/libcroco/csslint/csslint.1 new file mode 100644 index 0000000..a4c76a0 --- /dev/null +++ b/src/3rdparty/libcroco/csslint/csslint.1 @@ -0,0 +1,64 @@ +.\"Generated by db2man.xsl. Don't modify this, modify the source. +.de Sh \" Subsection +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.TH "CSSLINT" 1 "" "" "csslint Manual" +.SH NAME +csslint \- command line CSS tool +.SH "SYNOPSIS" + +.nf +\fBcsslint\fR [\fB--version\fR | \fB--cssom\fR] +.fi + +.SH "INTRODUCTION" + +.PP +The csslint program parses one or more CSS files, specified on the command line as \fIcssfile\fR\&. It prints various types of output, depending upon the options selected\&. It is useful for detecting errors both in CSS code and in the CSS parser itself\&. + +.PP +It is included in libcroco\&. + +.SH "OPTIONS" + +.TP +\fB--version\fR +Display the version of libcroco used\&. + +.TP +\fB--cssom\fR +parse a CSS file and builds a CSS object model\&. + +.SH AUTHOR +Written by Gael CHAMOULAUD (strider) <strider@freespiders.org> + +.SH REPORTING BUGS +Please report bugs at http://bugzilla.gnome.org. + +.SH COPYRIGHT +Copyright (C) 2002-2003 Dodji SEKETELI, Gael CHAMOULAUD. +.br +This is a free software; see the source for copying conditions. There is +NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. + +.SH SEE ALSO +.br +croco-config (1) + + diff --git a/src/3rdparty/libcroco/csslint/csslint.c b/src/3rdparty/libcroco/csslint/csslint.c new file mode 100644 index 0000000..3495eff --- /dev/null +++ b/src/3rdparty/libcroco/csslint/csslint.c @@ -0,0 +1,1011 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * csslint.c : a small tester program for libcroco. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Initial Author: Gael Chamoulaud. + * Main programmer: Dodji Seketeli + * Contributor: Rob Buis + * See COPYRGIGHTS file for copyright information. + */ + +#include "libcroco.h" +#include "cr-libxml-node-iface.h" +#include <libxml/xpath.h> + +#include <glib.h> +#include <string.h> + +/** + *The options data structure. + *The variable of this data structure are set + *during the parsing the command line by the + *parse_command_line() function. + */ +struct Options { + gboolean show_version; + gboolean use_cssom; + gboolean display_help; + gboolean evaluate; + gboolean dump_location; + gchar *author_sheet_path; + gchar *user_sheet_path; + gchar *ua_sheet_path; + gchar *xml_path; + gchar *xpath; + gchar **css_files_list; +}; + +struct SacContext { + gint level; + +}; + +static enum CRStatus sac_parse_and_display_locations (guchar * a_file_uri); + +static void parse_cmd_line (int a_argc, char **a_argv, + struct Options *a_options); + +static void display_version (void); + +static void display_usage (void); + +static enum CRStatus cssom_parse (guchar * a_file_uri); + +static enum CRStatus get_and_dump_node_style (xmlNode * a_node, + CRSelEng * a_sel_eng, + CRCascade * a_cascade); + +static enum CRStatus evaluate_selectors (gchar * a_xml_path, + gchar * a_author_sheet_path, + gchar * a_user_sheet_path, + gchar * a_ua_sheet_path, + gchar * a_xpath); + +/** + *Parses the command line. + *@param a_argc the argc parameter of the main routine. + *@param the argv parameter of the main routine. + *@param a_options out parameter the parsed options. + */ +static void +parse_cmd_line (int a_argc, char **a_argv, struct Options *a_options) +{ + int i = 0; + + g_return_if_fail (a_options); + + if (a_argc <= 1) { + display_usage (); + } + + for (i = 1; i < a_argc; i++) { + if (a_argv[i][0] != '-') + break; + + if ((!strcmp (a_argv[i], "-version")) || + (!strcmp (a_argv[i], "-v"))) { + a_options->show_version = TRUE; + } else if (!strcmp (a_argv[i], "--evaluate") || + !strcmp (a_argv[i], "-e")) { + for (i++; i < a_argc; i++) { + if (!strcmp (a_argv[i], "--author-sheet")) { + if (a_options->author_sheet_path) { + display_usage (); + exit (-1); + } + i++; + if (i >= a_argc + || a_argv[i][0] == '-') { + g_print ("--author-sheet should be followed by a path to the sheet\n"); + display_usage (); + exit (-1); + } + a_options->author_sheet_path = + a_argv[i]; + } else if (!strcmp + (a_argv[i], "--user-sheet")) { + if (a_options->user_sheet_path) { + display_usage (); + exit (-1); + } + i++; + if (i >= a_argc + || a_argv[i][0] == '-') { + g_print ("--user-sheet should be followed by a path to the sheet\n"); + display_usage (); + exit (-1); + } + a_options->user_sheet_path = + a_argv[i]; + } else if (!strcmp (a_argv[i], "--ua-sheet")) { + if (a_options->ua_sheet_path) { + display_usage (); + exit (-1); + } + i++; + if (i >= a_argc + || a_argv[i][0] == '-') { + g_print ("--ua-sheet should be followed by a path to the sheet\n"); + display_usage (); + exit (-1); + } + a_options->ua_sheet_path = a_argv[i]; + } else if (!strcmp (a_argv[i], "--xml")) { + i++; + if (i >= a_argc + || a_argv[i][0] == '-') { + g_print ("--xml should be followed by a path to the xml document\n"); + display_usage (); + exit (-1); + } + a_options->xml_path = a_argv[i]; + } else if (!strcmp (a_argv[i], "--xpath")) { + i++; + if (i >= a_argc + || a_argv[i][0] == '-') { + g_print ("--xpath should be followed by an xpath expression\n"); + display_usage (); + exit (-1); + } + a_options->xpath = a_argv[i]; + } else { + break; + } + } + if (!a_options->author_sheet_path + && !a_options->user_sheet_path && + !a_options->ua_sheet_path) { + g_print ("Error: you must specify at least one stylesheet\n"); + display_usage (); + exit (-1); + + } + if (!a_options->xpath) { + g_printerr + ("Error: you must specify an xpath expression using the --xpath option\n"); + display_usage (); + exit (-1); + + } + a_options->evaluate = TRUE; + } else if (!strcmp (a_argv[i], "--dump-location")) { + a_options->dump_location = TRUE; + a_options->use_cssom = FALSE; + } else if (!strcmp (a_argv[i], "--help") || + !strcmp (a_argv[i], "-h")) { + a_options->display_help = TRUE; + } else { + display_usage (); + exit (-1); + } + } + + if (i >= a_argc) { + a_options->css_files_list = NULL; + } else { + if (a_argv[i][0] == '-') { + display_usage (); + exit (-1); + } + a_options->css_files_list = &a_argv[i]; + } +} + +/** + *Displays the version text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_version (void) +{ + g_print ("%s\n", LIBCROCO_VERSION); +} + +/** + *Displays the usage text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_usage (void) +{ + g_print ("Usage: csslint <path to a css file>\n"); + g_print ("\t| csslint -v|--version\n"); + g_print ("\t| csslint --dump-location <path to a css file>\n"); + g_print ("\t| csslint <--evaluate | -e> [--author-sheet <path> --user-sheet <path> --ua-sheet <path>\n\t ] --xml <path> --xpath <xpath expression>\n"); +} + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +cssom_parse (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + CRStyleSheet *stylesheet = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + parser = cr_om_parser_new (NULL); + status = cr_om_parser_parse_file (parser, + a_file_uri, CR_ASCII, &stylesheet); + if (status == CR_OK && stylesheet) { + cr_stylesheet_dump (stylesheet, stdout); + g_print ("\n"); + cr_stylesheet_destroy (stylesheet); + } + cr_om_parser_destroy (parser); + + return status; +} + +static enum CRStatus +get_and_dump_node_style (xmlNode * a_node, + CRSelEng * a_sel_eng, CRCascade * a_cascade) +{ + CRPropList *prop_list = NULL, + *pair = NULL, + *prev_pair = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_node && a_sel_eng && a_cascade, + CR_BAD_PARAM_ERROR); + + status = cr_sel_eng_get_matched_properties_from_cascade + (a_sel_eng, a_cascade, a_node, &prop_list); + if (status != CR_OK) { + g_printerr ("Error: unable to run the selection engine\n"); + return CR_OK; + } + g_print ("Properties of xml element %s are:\n", a_node->name); + for (pair = prop_list; pair; pair = cr_prop_list_get_next (pair)) { + CRDeclaration *decl = NULL; + + cr_prop_list_get_decl (pair, &decl); + if (decl) { + prev_pair = cr_prop_list_get_prev (pair); + if (prev_pair) { + g_print ("\n"); + prev_pair = NULL; + } + cr_declaration_dump_one (decl, stdout, 2); + decl = NULL; + } + } + g_print ("\n=====================\n\n"); + + if (prop_list) { + cr_prop_list_destroy (prop_list); + prop_list = NULL; + } + + return CR_OK; +} + +static enum CRStatus +evaluate_selectors (gchar * a_xml_path, + gchar * a_author_sheet_path, + gchar * a_user_sheet_path, + gchar * a_ua_sheet_path, gchar * a_xpath) +{ + CRSelEng *sel_eng = NULL; + xmlDoc *xml_doc = NULL; + xmlXPathContext *xpath_context = NULL; + xmlXPathObject *xpath_object = NULL; + CRStyleSheet *author_sheet = NULL, + *user_sheet = NULL, + *ua_sheet = NULL; + CRCascade *cascade = NULL; + xmlNode *cur_node = NULL; + gint i = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_xml_path && a_xpath, CR_BAD_PARAM_ERROR); + + xml_doc = xmlParseFile (a_xml_path); + if (!xml_doc) { + g_printerr ("Error: Could not parse file %s\n", a_xml_path); + status = CR_ERROR; + goto end; + } + if (a_author_sheet_path) { + status = cr_om_parser_simply_parse_file + ((const guchar *) a_author_sheet_path, CR_ASCII, &author_sheet); + if (!author_sheet) { + g_printerr ("Error: Could not parse author sheet\n"); + } + } + if (a_user_sheet_path) { + status = cr_om_parser_simply_parse_file + ((const guchar *) a_user_sheet_path, CR_ASCII, &user_sheet); + if (!user_sheet) { + g_printerr ("Error: Could not parse author sheet\n"); + } + } + if (a_ua_sheet_path) { + status = cr_om_parser_simply_parse_file + ((const guchar *) a_ua_sheet_path, CR_ASCII, &ua_sheet); + if (!ua_sheet) { + g_printerr ("Error: Could not parse ua sheet\n"); + } + } + cascade = cr_cascade_new (author_sheet, user_sheet, ua_sheet); + + if (author_sheet) + cr_stylesheet_unref (author_sheet); + + if (user_sheet) + cr_stylesheet_unref (user_sheet); + + if (ua_sheet) + cr_stylesheet_unref (ua_sheet); + + if (!cascade) { + g_printerr ("Could not instantiate the cascade\n"); + status = CR_ERROR; + goto end; + } + sel_eng = cr_sel_eng_new (&cr_libxml_node_iface); + if (!sel_eng) { + g_printerr + ("Error: Could not instantiate the selection engine\n"); + status = CR_ERROR; + goto end; + } + xpath_context = xmlXPathNewContext (xml_doc); + if (!xpath_context) { + g_printerr + ("Error: Could not instantiate the xpath context\n"); + status = CR_ERROR; + goto end; + } + xpath_object = xmlXPathEvalExpression ((const xmlChar *) a_xpath, xpath_context); + if (!xpath_object) { + g_printerr ("Error: Could not evaluate xpath expression\n"); + status = CR_ERROR; + goto end; + } + if (xpath_object->type != XPATH_NODESET || !xpath_object->nodesetval) { + g_printerr + ("Error: xpath does not evalualuate to a node set\n"); + status = CR_ERROR; + goto end; + } + + for (i = 0; i < xpath_object->nodesetval->nodeNr; i++) { + cur_node = xpath_object->nodesetval->nodeTab[i]; + if (cur_node->type == XML_ELEMENT_NODE) { + status = get_and_dump_node_style (cur_node, sel_eng, + cascade); + } + } + + end: + + if (xpath_context) { + xmlXPathFreeContext (xpath_context); + xpath_context = NULL; + } + if (xpath_object) { + xmlXPathFreeObject (xpath_object); + xpath_object = NULL; + } + if (sel_eng) { + cr_sel_eng_destroy (sel_eng); + sel_eng = NULL; + } + if (cascade) { + cr_cascade_destroy (cascade); + cascade = NULL; + } + if (xml_doc) { + xmlFreeDoc (xml_doc); + xml_doc = NULL; + } + + return status; +} + +/*************************** + *SAC related stuff for the + *line/col annotation stylesheet + *dumping + ***************************/ +static void +start_document (CRDocHandler * a_this) +{ + struct SacContext *context = NULL; + + g_return_if_fail (a_this); + + context = g_try_malloc (sizeof (struct SacContext)); + if (!context) { + cr_utils_trace_info ("instantiation of sac context failed"); + return; + } + cr_doc_handler_set_ctxt (a_this, context); +} + +static void +end_document (CRDocHandler * a_this) +{ + struct SacContext *context = NULL; + + g_return_if_fail (a_this); + + cr_doc_handler_get_ctxt (a_this, (gpointer *) (gpointer) & context); + if (context) { + g_free (context); + context = NULL; + } +} + +static void +charset (CRDocHandler *a_this, + CRString *a_charset, + CRParsingLocation *a_charset_sym_location) +{ + gchar *str = NULL ; + + g_return_if_fail (a_this && a_charset && a_charset_sym_location) ; + + str = (gchar*)cr_string_peek_raw_str (a_charset) ; + if (str) { + g_print ("\n\n@charset \"%s\";\n\n", str) ; + str = NULL ; + } else { + return ; + } + g_print ("/********************************************\n") ; + g_print (" * Parsing location information of the @charset rule\n") ; + g_print (" ********************************************/\n") ; + if (a_charset_sym_location) { + str = cr_parsing_location_to_string (a_charset_sym_location, 0) ; + if (str) { + g_print (" /*@charset*/\n") ; + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + } + str = (gchar*) cr_string_peek_raw_str (a_charset) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = NULL ; + } + str = cr_parsing_location_to_string (&a_charset->location, 0) ; + if (str) { + g_print (" /*%s*/\n\n", str) ; + g_free (str) ; + str = NULL ; + } +} + +static void +import_style (CRDocHandler *a_this, + GList *a_media_list, + CRString *a_uri, + CRString *a_uri_default_ns, + CRParsingLocation *a_location) +{ + gchar *str = NULL ; + GString *gstr = NULL ; + GList *cur_media = NULL ; + + g_return_if_fail (a_this && a_location) ; + + gstr = g_string_new (NULL) ; + if (!gstr) { + cr_utils_trace_info ("Out of memory error") ; + return ; + } + for (cur_media = a_media_list ; + cur_media ; + cur_media = g_list_next (cur_media)) { + str = (gchar*)cr_string_peek_raw_str + ((CRString*)cur_media->data) ; + if (str) { + if (g_list_previous (cur_media)) { + g_string_append_printf (gstr, ", %s", + str) ; + } else { + g_string_append_printf (gstr, "%s", + str) ; + } + } + } + str = (gchar*)cr_string_peek_raw_str (a_uri) ; + if (str) { + g_print ("@import url(\"%s\") ", str) ; + if (gstr) { + g_print ("%s;\n\n", gstr->str) ; + } + str = NULL ; + } + str = cr_parsing_location_to_string (a_location, 0) ; + if (str) { + g_print ("/*****************************************************\n") ; + g_print (" *Parsing location information for the @import rule\n") ; + g_print (" ******************************************************/\n\n") ; + g_print (" /*@import*/\n") ; + g_print (" /*%s*/\n\n", str) ; + g_free (str) ; + str = NULL ; + } + + str = (gchar*)cr_string_peek_raw_str (a_uri) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = cr_parsing_location_to_string + (&a_uri->location, 0) ; + if (str) { + g_print (" /*%s*/\n\n", str) ; + g_free (str) ; + str = NULL ; + } + } + + for (cur_media = a_media_list ; + cur_media ; + cur_media = g_list_next (cur_media)) { + str = (gchar*)cr_string_peek_raw_str + ((CRString*)cur_media->data) ; + if (str) { + g_print (" /*%s*/\n", str) ; + } + str = cr_parsing_location_to_string + (&((CRString*)cur_media->data)->location, 0) ; + if (str) { + g_print (" /*%s*/\n\n", str) ; + g_free (str) ; + str = NULL ; + } + } + + if (gstr) { + g_string_free (gstr, TRUE) ; + gstr = NULL ; + } +} + +static void +start_font_face (CRDocHandler *a_this, + CRParsingLocation *a_location) +{ + gchar *str = NULL ; + + g_print ("@font-face {\n") ; + g_print ("/******************************************************\n") ; + g_print (" Parsing location information for the @font-face rule\n") ; + g_print (" ******************************************************/\n\n") ; + + g_print (" /*@font-face*/\n") ; + if (a_location) { + str = cr_parsing_location_to_string (a_location, 0) ; + } + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } +} + +static void +end_font_face (CRDocHandler *a_this) +{ + g_print ("}\n") ; +} + +static void +start_media (CRDocHandler *a_this, + GList *a_media_list, + CRParsingLocation *a_location) +{ + GList *cur_media = NULL ; + gchar *str = NULL ; + + g_print ("@media ") ; + for (cur_media = a_media_list ; + cur_media ; + cur_media = g_list_next (cur_media)) { + CRString *crstr = cur_media->data ; + if (crstr) { + str = (gchar*)cr_string_peek_raw_str (crstr) ; + if (str) { + if (cur_media->prev) { + g_print (", %s", str) ; + } else { + g_print ("%s", str) ; + } + } + } + } + /***************************** + *new print parsing locations + *****************************/ + g_print ("\n /*@media*/\n") ; + if (a_location) + str = cr_parsing_location_to_string (a_location, + 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + for (cur_media = a_media_list ; + cur_media ; + cur_media = g_list_next (cur_media)) { + CRString *crstr = cur_media->data ; + if (crstr) { + str = (gchar*)cr_string_peek_raw_str (crstr) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = cr_parsing_location_to_string + (&crstr->location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + } + } + } + g_print ("\n{\n") ; +} + +static void +end_media (CRDocHandler *a_this, + GList *a_media_list) +{ + g_print ("\n}\n") ; +} + +static void +start_page (CRDocHandler *a_this, + CRString *a_name, + CRString *a_pseudo_page, + CRParsingLocation *a_location) +{ + gchar *str = NULL ; + + g_print ("@page ") ; + if (a_name) + str = (gchar*)cr_string_peek_raw_str (a_name) ; + if (str) { + g_print ("%s ", str) ; + } + if (a_pseudo_page) + str = (gchar*) cr_string_peek_raw_str (a_pseudo_page) ; + if (str) { + g_print (":%s", str) ; + str = NULL ; + } + /************************************* + *print parsing location information + ************************************/ + g_print ("\n\n /*@page*/\n") ; + if (a_location) + str = cr_parsing_location_to_string + (a_location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + if (a_name) + str = (gchar*)cr_string_peek_raw_str (a_name) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = cr_parsing_location_to_string + (&a_name->location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + } + if (a_pseudo_page) + str = (gchar*) cr_string_peek_raw_str + (a_pseudo_page) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = cr_parsing_location_to_string + (&a_pseudo_page->location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + } + g_print ("\n{\n") ; +} + +static void +end_page (CRDocHandler *a_this, + CRString *a_name, + CRString *pseudo_page) +{ + g_print ("}\n") ; +} + +static void +dump_location_annotated_simple_sel (CRSimpleSel *a_this) +{ + CRSimpleSel *cur_simple_sel = a_this ; + CRAdditionalSel *cur_add_sel = NULL ; + gchar *str0 = NULL ; + + g_return_if_fail (a_this) ; + + /*first, display the entire simple sel*/ + str0 = (gchar *) cr_simple_sel_one_to_string + (cur_simple_sel) ; + if (str0) { + g_print ("/*%s*/\n", str0) ; + g_free (str0) ; + str0 = NULL ; + } + g_print ("/*") ; + cr_parsing_location_dump + (&cur_simple_sel->location, 0, + stdout); + g_print ("*/\n") ; + + /*now display the details of the simple sel*/ + if (cur_simple_sel->name) { + str0 = (gchar*) cr_string_peek_raw_str + (cur_simple_sel->name) ; + if (str0) { + g_print (" /*%s*/\n", str0) ; + str0 = NULL ; + } + str0 = cr_parsing_location_to_string + (&cur_simple_sel->name->location, + 0) ; + if (str0) { + g_print (" /*%s*/\n", str0) ; + g_free (str0) ; + str0 = NULL ; + } + } + for (cur_add_sel = cur_simple_sel->add_sel; + cur_add_sel; + cur_add_sel = cur_add_sel->next) { + str0 = (gchar *) cr_additional_sel_one_to_string + (cur_add_sel) ; + if (str0) { + g_print ("\n /*%s*/\n", str0) ; + g_free (str0) ; + str0 = NULL ; + } + str0 = cr_parsing_location_to_string + (&cur_add_sel->location, 0) ; + if (str0) { + g_print (" /*%s*/\n", str0) ; + g_free (str0) ; + str0 = NULL ; + } + } +} + +static void +start_selector (CRDocHandler * a_this, CRSelector * a_selector_list) +{ + struct SacContext *context = NULL; + CRSelector *cur_sel = NULL ; + CRSimpleSel *cur_simple_sel = NULL ; + + g_return_if_fail (a_this); + + cr_doc_handler_get_ctxt (a_this, (gpointer *) (gpointer) & context); + if (context) { + context->level++; + } + cr_selector_dump (a_selector_list, stdout); + g_print (" {\n") ; + g_print ("/************************************************\n") ; + g_print (" *Parsing location information of the selector\n") ; + g_print (" ************************************************/\n") ; + + for (cur_sel = a_selector_list; + cur_sel ; + cur_sel = cur_sel->next) { + for (cur_simple_sel = cur_sel->simple_sel ; + cur_simple_sel ; + cur_simple_sel = cur_simple_sel->next) { + + dump_location_annotated_simple_sel + (cur_simple_sel) ; + } + } +} + +static void +end_selector (CRDocHandler * a_this, + CRSelector *a_selector_list) +{ + struct SacContext *context = NULL; + + g_return_if_fail (a_this); + + cr_doc_handler_get_ctxt (a_this, (gpointer *) (gpointer) & context); + if (context) { + context->level--; + } + g_print (" }\n") ; +} + +static void +property (CRDocHandler *a_this, + CRString *a_name, + CRTerm *a_expr, + gboolean a_is_important) +{ + gchar *str = NULL ; + CRTerm *cur_term = NULL ; + + str = (gchar*) cr_string_peek_raw_str (a_name) ; + if (str) { + g_print ("\n\n") ; + g_print ("%s", str) ; + str = NULL ; + if (a_expr) { + str = (gchar *) cr_term_to_string (a_expr) ; + if (str) { + g_print (" : %s;\n\n", str) ; + g_free (str) ; + str = NULL ; + } + } else { + g_print (";\n\n") ; + } + } + + /*Now dump each part of the property declaration*/ + + g_print ("\n") ; + g_print ("/************************************************\n") ; + g_print (" *Parsing location information of the property\n") ; + g_print (" ************************************************/\n") ; + + str = (gchar*) cr_string_peek_raw_str (a_name) ; + if (str) { + g_print (" /*%s*/\n", str) ; + str = NULL ; + } + str = cr_parsing_location_to_string (&a_name->location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + + for (cur_term = a_expr ; + cur_term; + cur_term = cur_term->next) { + str = (gchar *) cr_term_one_to_string (cur_term) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + str = cr_parsing_location_to_string + (&cur_term->location, 0) ; + if (str) { + g_print (" /*%s*/\n", str) ; + g_free (str) ; + str = NULL ; + } + } +} + + +static enum CRStatus +sac_parse_and_display_locations (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CRDocHandler *sac_handler = NULL; + CRParser *parser = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + parser = cr_parser_new_from_file (a_file_uri, CR_UTF_8); + if (!parser) { + cr_utils_trace_info ("parser instantiation failed"); + return CR_ERROR; + } + sac_handler = cr_doc_handler_new (); + if (!sac_handler) { + cr_utils_trace_info ("sac handler instantiation failed"); + status = CR_OUT_OF_MEMORY_ERROR; + goto cleanup; + } + sac_handler->start_document = start_document ; + sac_handler->end_document = end_document ; + sac_handler->charset = charset ; + sac_handler->import_style = import_style ; + sac_handler->start_font_face = start_font_face ; + sac_handler->end_font_face = end_font_face ; + sac_handler->start_media = start_media ; + sac_handler->end_media = end_media ; + sac_handler->start_page = start_page ; + sac_handler->end_page = end_page ; + sac_handler->start_selector = start_selector; + sac_handler->end_selector = end_selector; + sac_handler->property = property ; + + cr_parser_set_sac_handler (parser, sac_handler) ; + status = cr_parser_parse (parser) ; + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + return status; +} + +int +main (int argc, char **argv) +{ + struct Options options; + enum CRStatus status = CR_OK; + + memset (&options, 0, sizeof (struct Options)); + options.use_cssom = TRUE; + parse_cmd_line (argc, argv, &options); + + if (options.show_version == TRUE) { + display_version (); + return 0; + } + + if (options.display_help == TRUE) { + display_usage (); + return 0; + } + if (options.use_cssom == TRUE) { + if (options.evaluate == TRUE) { + status = evaluate_selectors + (options.xml_path, + options.author_sheet_path, + options.user_sheet_path, + options.ua_sheet_path, options.xpath); + } else if (options.css_files_list != NULL) { + status = cssom_parse ((guchar *) options.css_files_list[0]); + } + } else if (options.dump_location == TRUE) { + if (options.css_files_list) { + status = sac_parse_and_display_locations + ((guchar *) options.css_files_list[0]) ; + } else { + display_usage () ; + return -1 ; + } + } + + return (status == CR_OK) ? 0 : -2; +} diff --git a/src/3rdparty/libcroco/docs/Makefile.am b/src/3rdparty/libcroco/docs/Makefile.am new file mode 100644 index 0000000..ece8c4b --- /dev/null +++ b/src/3rdparty/libcroco/docs/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS=examples reference + +EXTRA_DIST=usage.txt diff --git a/src/3rdparty/libcroco/docs/design/parser-architecture.txt b/src/3rdparty/libcroco/docs/design/parser-architecture.txt new file mode 100644 index 0000000..67b7713 --- /dev/null +++ b/src/3rdparty/libcroco/docs/design/parser-architecture.txt @@ -0,0 +1,146 @@ +Libcroco parser architecture +----------------------------- + +Author: Dodji Seketeli <dodji@seketeli.org> + +$Id$ + +I) Forethoughts. +=================== + +Libcroco's parser is a simple recursive descent parser. +The major design focus has been simplicity, reliability and +conformance. + +Simplicity +----------- +We want the code to be maintainable by anyone who knows the CSS spec +and who knows how to code in C. Therefore, we avoid to overuse +the C preprocessor magic and all the tricks that tend to turn C into +a maintenance nightmare. + +We also try to adhere to the Gnome coding guidelines specified +at http://developer.gnome.org/doc/guides/programming-guidelines. + + +Reliability +----------- +Each single function of the libcroco library should never crash, +and this, whatever the arguments it takes. +As a consequence we tend to be paranoid when it comes to check +pointers values before dereferencing them for example... + +Conformance +----------- +We try to stick to the CSS spec. We know this is almost impossible to achieve +given the resources we have but we think it is a sane target to chase. + +II) Overall architecture +========================= +The parser is organized around several main classes: + +1/ CRInput +2/ CRTknzr (Tokenizer or lexer) +3/ CRParser +4/ CROMParser + +II.1 The CRInput class +----------------------- +The CRInput class provides the abstraction of +an utf8-encoded character stream. + +Ideally, it should abstract local data sources +(local files and in-memory buffers) +and remote data sources (sockets, url-identified resources) but for the +moment, it can only abstract local data sources. + +Adding a new type of data source should be transparent for the +classes that already use CRInput. After all, this is what abstraction is about :) + + +II.2 The CRTknzr class +---------------------- +The main job of the tokenizer (or lexer) is to +provide a get_next_token() method. +This methods returns the next CSS token found in the input stream. +(Note that the input stream here is an instance of CRInput). + +This provides an extremely useful facility to the parser. + +II.3 The CRParser class +------------------------- +The core of the parser. + +The main job of this class is to provide a cr_parser_parse_stylesheet() +method. During the parsing (the execution of the cr_parser_stylesheet()) +the parser sends events to notify the application when it encounters +remarkable CSS constructions. This is the SAC (Simple API for CSS) API model. + +To achieve that task, almost each production of the CSS grammar +has a matching parsing function (or method) in this class. + +For example, the following production named "ruleset" (specified in the +CSS2 spec in appendix D.1): + +ruleset : selector [ ',' S* selector ]* + '{' S* declaration [ ';' S* declaration ]* '}' S* + +is "implemented" by the cr_parser_parse_ruleset() method. + +The same thing applies for the "selector" production: + +selector : simple_selector [ combinator simple_selector ]* + +which is implemented by the cr_parser_parse_selector() method... and so on +and so forth. + +II.3.1 Structure of a parsing method. +------------------------------------- +A parsing method (e.g cr_parser_parse_ruleset()) is there +to: + + * try to recognize a substring of the incoming character string + as something that matches a given CSS grammar production. + + e.g: the job of the cr_parser_parse_ruleset() is to try + to recognize if "what" comes next in the input stream + is a CSS2 "ruleset". + + * build a basic abstract data structure to + store the information encountered + during the parsing of the current character string. + + eg: cr_parser_parse_declaration() has the following prototype: + + enum CRStatus + cr_parser_parse_declaration (CRParser *a_this, GString **a_property, + CRTerm **a_value) ; + + In case of successful parsing, this method returns + (via its parameters) the property _and_ the + value of the CSS2 declaration. + Note that a CSS2 declaration is specified as follows: + + declaration : property ':' S* expr prio? + | /* empty */ + + * After completion, say if the parsing has succeeded or not. + + eg: cr_parser_parse_declaration() returns CR_OK if the + parsing has succeeded, and error code otherwise. Obviously, + the out parameters "a_property" and "a_value" are valid if and only + if the return value is CR_OK. + + * whenever the function is parsing a construct that must + be notified to the user as part of the SAC API spec, notify + the user by calling the right SAC callback. + + * if the parsing failed, leave the position in the stream unchanged. + That is, the position in the character stream should be as if + the parsing function hasn't been called at all. + + +II.4 The selection Engine. +-------------------------- + +Hmmh, I should kick my ass to write this down ...
\ No newline at end of file diff --git a/src/3rdparty/libcroco/docs/design/sel-instr.txt b/src/3rdparty/libcroco/docs/design/sel-instr.txt new file mode 100644 index 0000000..6b19389 --- /dev/null +++ b/src/3rdparty/libcroco/docs/design/sel-instr.txt @@ -0,0 +1,64 @@ +Draft of the libcroco selector internal instruction set. +********************************************************* + +READERS SHOULD READ THE CHAPTER 5 of THE CSS2 CSS2 SPEC INTITLED +"Selectors" FIRST. + +I) Introduction +'''''''''''''''''''' +This is the instructions set understood by the libcroco +sel-eng.c module (Selection engine). + +The purpose of the selection engine is to basically to say whether if a given +xml node is matched by a given css2 selector or not. + +II) Rationale +'''''''''''''''''''' +For the sake of performance (mostly processing speed) each CSS2 +selector is compiled into a sequences of atomic selection instructions +that are easily executable by the selection engine. + +III) Selection instruction set overview +'''''''''''''''''''''''''''''''''''''''' + +Each selection instruction returns a boolean value (TRUE or FALSE). +The execution of a sequence of selection instruction stops at the +first instruction that returns a FALSE value and the selection engine +returns returns the value FALSE to say that the current xml node +is matched by the CSS2 selection expression being evaluated. + +Note that during the evaluation of a CSS2 selection expression, +all the contextual information are stored into an evaluation context. +For example, the context will hold a pointer to the xml node the +selection engine is trying to match. + +III.1) The instruction set. +''''''''''''''''''''''''''' + +set-cur-node 'a_node' +---------------------- +a_node: an xml node +Sets the current xml node (in the context) to a_node. + +match-n-ancestor 'a_n' 'a_parent' +---------------------------------- +a_parent: a string. +a_n: a number. The depth of the ancestor + +Returns true if the current xml node has an ancestor +located at a depth 'n' (going upward from the current node) +and named 'a_parent'. An ancestor located at depth '0' designates +the current xml node. An ancesstor located at depth '1' designates +the parent of the current xml node etc ... + +match-any +--------- +Always returns true. + +match-first-child 'a_name' +-------------------------- +Returns true if the current xml element's name equal 'a_name' and +if the current xml element is the first child of its parent. + +TODO: continue reading the chapter 5 of the css2 spec and finish +the design of this instruction set. diff --git a/src/3rdparty/libcroco/docs/examples/Makefile.am b/src/3rdparty/libcroco/docs/examples/Makefile.am new file mode 100644 index 0000000..e960594 --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST=cssom-example-1.c sac-example-1.c sac-example-2.c diff --git a/src/3rdparty/libcroco/docs/examples/cssom-example-1.c b/src/3rdparty/libcroco/docs/examples/cssom-example-1.c new file mode 100644 index 0000000..85079ce --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/cssom-example-1.c @@ -0,0 +1,109 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/** + *This is an example that shows how to use + *the CSSOM api of the libcroco CSS2 parsing library. + *It just parses the CSS document given in argument and + *it dumps it (serializes) it on the screen. + * + *To compile it using gcc, type + * + *gcc -g -Wall `croco-0.6-config --cflags` `croco-0.6-config --libs` -o cssom-example-1 cssom-example-1.c + * + *Prior to that, you must have compiled and installed libcroco, of course. + * + *@author Dodji Seketeli + */ + +#include <string.h> +#include <libcroco/libcroco.h> + +/** + *Displays the usage of this program. + *@param prg_name the name of the program. + */ +void +display_usage (char *prg_name) +{ + printf ("\nusage: %s [options] <css file to parse>\n\n", + prg_name) ; + printf ("\twhere options are:\n") ; + printf ("\t--help|h\tdisplays this help\n") ; + printf ("\n") ; +} + + +/** + *Main entry point. + *This function illustrates a way to use libcroco. + *In this example, we will use a CSS Object Model parser + *to parse a cascading style sheet and dump what we have parsed on stdout. + * + *The goal of the object model parser is to parse a css and build + *an abstract tree out of it. One can then walk the tree to perform + *whatever action he wants. In our case, the function used to + *dump the tree on stdout will walk the tree and dump each one of its + *components (a.k.a. css statements). + */ +int +main (int argc, char **argv) +{ + short i = 0 ; + enum CRStatus status = CR_OK ; + CRStyleSheet *stylesheet = NULL ; + + /*first parse command line arguments*/ + for (i = 1 ; i < argc ; i++) + { + if (argv[i][0] != '-') + break ; + if (!strcmp (argv[i],"--help") + || !strcmp (argv[i], "-h")) + { + display_usage (argv[0]) ; + return 0 ; + } + else + { + display_usage (argv[0]) ; + return 0 ; + } + } + if (i >= argc) + { + display_usage (argv[0]) ; + return 0; + } + + /***************************************************** + *Enough plumbering... now, the real libcroco stuffs. + ***************************************************/ + + /* + *What we want here is to simply parse + *a CSS document using the cssom api. + */ + status = cr_om_parser_simply_parse_file ((const guchar*)argv[i] /*sheet*/, + CR_ASCII /*the encoding*/, + &stylesheet) ; + if (status == CR_OK && stylesheet) + { + /* + *everything went well, + *so dump the stylesheet on stdout. + */ + cr_stylesheet_dump (stylesheet, stdout) ; + } + + if (stylesheet) + { + /* + *free the the memory used to hold the css + *object model + */ + cr_stylesheet_destroy (stylesheet) ; + stylesheet = NULL ; + } + + return 0 ; +} diff --git a/src/3rdparty/libcroco/docs/examples/sac-example-1.c b/src/3rdparty/libcroco/docs/examples/sac-example-1.c new file mode 100644 index 0000000..074fc07 --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/sac-example-1.c @@ -0,0 +1,198 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/** + *This test example shows how to use the SAC api. + * + *This features a simple parser that says "hey" when + *it encounters the beginning of a CSS ruleset, and "woohoo" + *at the end of a CSS ruleset. + * + *To compile this file, type: + * + *gcc -g -Wall -o sac-example-1 `croco-0.6-config --cflags` `croco-0.6-config --libs` sac-example-1.c + * + *Make sure you have compiled and installed libcroco prior to trying to + *compile this file :) + * + *Once you have compiled it, type: + * + *./sac-example-1 <a-path-to-a-css-file> + * + *to try it on a CSS file of your choice. + * + *Initial Author: Dodji Seketeli <Dodji 47 seketeli dot org> + */ + +#include <string.h> +#include <libcroco/libcroco.h> + +/** + *This is a callback function that will + *be called at the beginning of each css ruleset. + *@param a_handler a pointer to the current sac + *document handler + *@param a_selector a pointer to the selector. + *of the current ruleset. + */ +static void +start_selector_cb (CRDocHandler *a_handler, + CRSelector *a_selector) +{ + printf ("==========================================\n") ; + printf ("Hey, this is the beginning of a ruleset\n") ; +} + +/** + *This is a callback function that will be called at the end + *of the each css ruleset. + */ +static void +end_selector_cb (CRDocHandler *a_handler, + CRSelector *a_selector) +{ + printf ("Woohoo, this is the end of a ruleset\n") ; + printf ("======================================\n\n") ; +} + +/** + *Displays some information about how to use this program. + *@param a_prog_name the name of the current program. + */ +void +display_usage (unsigned char *a_prog_name) +{ + unsigned char *prog_name = a_prog_name ; + + if (!prog_name) + { + prog_name = (unsigned char*)"sac-example-1" ; + } + + printf ("usage: %s [--help] | <css file name>\n", prog_name) ; +} + +int +main (int argc, char **argv) +{ + unsigned short i = 0 ; + unsigned char * file_path = NULL ; + CRParser * parser = NULL ; + CRDocHandler *sac_handler = NULL ; + + if (argc <= 1) + { + display_usage ((unsigned char*)argv[0]) ; + return -1 ; + } + + /* + *Let's parse the + *command line arguments of this + *program in this loop. + */ + for (i=1 ; i < argc ;i++) + { + if (*argv[i] != '-') + break ; + + if (!strcmp (argv[i], "--help") + || !strcmp (argv[i], "-h")) + { + display_usage ((unsigned char*)argv[0]) ; + return -1; + } + else + { + /* + *no other option is + *available now, so this is + *a bit redundant... + */ + display_usage ((unsigned char*)argv[0]) ; + } + } + + if (i > argc) + { + /* + *no file name has been given + *in parameter, go out. + */ + return -1 ; + } + + /**************************************** + *Now, the real libcroco related stuffs... + ****************************************/ + + file_path = (unsigned char*)argv[i] ; + + /* + *Instantiate the libcroco parser. + */ + parser = cr_parser_new_from_file (file_path, + CR_ASCII) ; + if (!parser) + { + /* + *Damned, something bad happened ... + */ + return -1; + } + + /* + *Instantiates the SAC document handler. + */ + sac_handler = cr_doc_handler_new () ; + if (!sac_handler) + { + /* + *Argh, something bad happened here :-\ + *Let's release the resources we allocated + *and let's get out. + */ + + cr_parser_destroy (parser) ; + return -1; + } + + /****************** + *Sets some of the sac document handlers. + ****************/ + + /* + *This sac handler callback function will get called by the parser + *each time it encounters the beginning of a ruleset. + */ + sac_handler->start_selector = start_selector_cb ; + + /* + *This sac handler callback function will get called by the parser + *each time it encounters the end of a ruleset. + */ + sac_handler->end_selector = end_selector_cb ; + + /* + *Let's register our sac handler into the parser. + */ + cr_parser_set_sac_handler (parser, sac_handler) ; + + /* + *Now, let's do the parsing !!! + */ + cr_parser_parse (parser) ; + + /******************************************************* + *End of the parsing. A lot of sentences beginning with "Hey" + *may have been printed on the screen... + ***********************************************/ + + /* + *Time to free the resources we allocated. + */ + cr_parser_destroy (parser) ; + + cr_doc_handler_unref (sac_handler) ; + + return 0 ; +} diff --git a/src/3rdparty/libcroco/docs/examples/sac-example-2.c b/src/3rdparty/libcroco/docs/examples/sac-example-2.c new file mode 100644 index 0000000..63b002d --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/sac-example-2.c @@ -0,0 +1,349 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ +/** + *This test example shows how to use the SAC api. + * + *This features a simple parser that prints the selector list + *and the properties list of each CSS ruleset found. + *It also prints the number of properties found in each CSS ruleset. + * + *At the end of the parsing, it a prints the number of rulesets found + *in the CSS document. + * + *To to this, several handler callbacks have been registered. + *We have also created a data structure that we call a parsing context. + *This parsing context stores the data necessary to achieve the calculation + *done during the parsing (count the number of rulesets and the number + *of properties per ruleset) + *The parsing context itself is stored in the "app_data" field of the sac handler. + *This field is there to provide applications with a + *place to store the custom data they want to be able to get/set during the parsing. + * + *To compile this file, type: + * + *gcc -g -Wall -o sac-example-2 `croco-0.6-config --cflags` `croco-0.6-config --libs` sac-example-2.c + * + *Make sure you have compiled and installed libcroco prior to trying to + *compile this file :) + * + *Once you have compiled it, type: + * + *./sac-example-2 <a-path-to-a-css-file> + * + *to try it on a CSS file of your choice. + * + *Initial Author: Dodji Seketeli <Dodji 47 seketeli dot org> + */ +#include <string.h> +#include <stdlib.h> +#include <libcroco/libcroco.h> + +/** + *A Context that will hold the + *variables necessary to count the number + *of rulesets and the number of properties + *per ruleset. + */ +struct MyFooContext +{ + /**the total number of rulesets in the stylesheet.*/ + int nb_rulesets ; + + /**the number of property per ruleset.*/ + int nb_props_per_ruleset ; +} ; + +/** + *This callback is called only once, at the beginning of + *the CSS Document. + *So here, we will allocate a custom parsing context + *where we will store data necessary for us to + *count the number of rulesets and properties found in + *the CSS document. + *@param a_handler the sac handler. + */ +static void +start_document_cb (CRDocHandler *a_handler) +{ + struct MyFooContext * parsing_context = NULL ; + + /* + *Allocate the parsing context. + *Our custom parsing context. + */ + parsing_context = (struct MyFooContext*) malloc + (sizeof (struct MyFooContext)) ; + if (!parsing_context) + { + /* + *the system ran out of memory. Advertise it and + *stop the program. + */ + fprintf (stderr, "program ran out of memory") ; + exit (-1) ; + } + + /* + *Initialize the newly allocated custom parsing context + *to zero. + */ + memset (parsing_context, 0, sizeof (struct MyFooContext)) ; + + /* + *Store the parsing context in the document handler. + *The app_data field CRDocHandler is especially there + *for that: give applications a place to store some data + *during the parsing. + */ + a_handler->app_data = parsing_context ; +} + +/** + *This callback function will + *be called at the beginning of each css ruleset. + *@param a_handler a pointer to the current sac + *document handler + *@param a_selector a pointer to the selector. + *of the current ruleset. + */ +static void +start_selector_cb (CRDocHandler *a_handler, + CRSelector *a_selector) +{ + struct MyFooContext *context = NULL ; + + context = (struct MyFooContext*) a_handler->app_data ; + if (!context) + return ; + context->nb_props_per_ruleset = 0 ; + + cr_selector_dump (a_selector, stdout) ; + printf (" {\n") ; + +} + +/** + *This callback function is called when + *the parser encounters a CSS property. + *@param a_handler the SAC handler. + *@param a_name string that contains the + *name of the property. + *@param a_value the value of the property. + */ +static void +property_cb (CRDocHandler *a_handler, + CRString *a_name, + CRTerm *a_value, + gboolean a_important) +{ + struct MyFooContext *context = NULL ; + + context = (struct MyFooContext *)a_handler->app_data ; + + if (!context || !a_name) + return ; + context->nb_props_per_ruleset ++ ; + + printf ("%s : ", cr_string_peek_raw_str (a_name)) ; + cr_term_dump (a_value, stdout) ; + printf ("\n") ; +} + + +/** + *This is a callback function that will be called at the end + *of the each css ruleset. + */ +static void +end_selector_cb (CRDocHandler *a_handler, + CRSelector *a_selector) +{ + struct MyFooContext *context = NULL ; + + context = (struct MyFooContext*)a_handler->app_data ; + if (!context) + return ; + context->nb_rulesets ++ ; + printf ("\n}\n") ; + printf ("**Number of properties in this ruleset: %d\n\n\n", + context->nb_props_per_ruleset) ; +} + +/** + *This callback is called only once at the end + *of the CSS document. + *@param a_handler the SAC handler. + */ +static void +end_document_cb (CRDocHandler *a_handler) +{ + struct MyFooContext *context = NULL ; + + context = (struct MyFooContext*) a_handler->app_data ; + if (!context) + return ; + + printf ("\nTotal number of rulesets: %d\n", + context->nb_rulesets) ; + + free (context) ; + a_handler->app_data = NULL ; +} + +/** + *Displays some information about how to use this program. + *@param a_prog_name the name of the current program. + */ +void +display_usage (unsigned char *a_prog_name) +{ + unsigned char *prog_name = a_prog_name ; + + if (!prog_name) + { + prog_name = (unsigned char*) "sac-example-1" ; + } + + printf ("usage: %s [--help] | <css file name>\n", prog_name) ; +} + +int +main (int argc, char **argv) +{ + unsigned short i = 0 ; + unsigned char * file_path = NULL ; + CRParser * parser = NULL ; + CRDocHandler *sac_handler = NULL ; + + if (argc <= 1) + { + display_usage ((unsigned char*)argv[0]) ; + return -1 ; + } + + /* + *Let's parse the + *command line arguments of this + *program in this loop. + */ + for (i=1 ; i < argc ;i++) + { + if (*argv[i] != '-') + break ; + + if (!strcmp (argv[i], "--help") + || !strcmp (argv[i], "-h")) + { + display_usage ((unsigned char*)argv[0]) ; + return -1; + } + else + { + /* + *no other option is + *available now, so this is + *a bit redundant... + */ + /*display_usage ((unsigned char*)argv[0]) ;*/ + } + } + + if (i > argc) + { + /* + *no file name has been given + *in parameter, go out. + */ + return -1; + } + + /**************************************** + *Now, the real libcroco related stuffs... + ****************************************/ + + file_path = (unsigned char*)argv[i] ; + + /* + *Instantiate the libcroco parser. + */ + parser = cr_parser_new_from_file (file_path, + CR_ASCII) ; + if (!parser) + { + /* + *Damned, something bad happened ... + */ + return -1 ; + } + + /* + *Instantiates the SAC document handler. + */ + sac_handler = cr_doc_handler_new () ; + if (!sac_handler) + { + /* + *Argh, something bad happened here :-\ + *Let's release the resources we allocated + *and let's get out. + */ + + cr_parser_destroy (parser) ; + return -1 ; + } + + /**************************************** + *Set some of the sac document handlers. + ****************************************/ + + /* + *This callback function will be called by the parser + *only once, at the beginning of the CSS Document. + */ + sac_handler->start_document = start_document_cb ; + + /* + *This callback function will be called by the parser + *only once, at the end of the CSS Document. + */ + sac_handler->end_document =end_document_cb ; + + /* + *This callback function will be called by the parser + *each time it encounters the beginning of a ruleset. + */ + sac_handler->start_selector = start_selector_cb ; + + /* + *This callback function will be called by the parser + *each time it encounters the beginning of a ruleset. + */ + sac_handler->property = property_cb ; + + /* + *This sac handler callback function will be called by the parser + *each time it encounters the end of a ruleset. + */ + sac_handler->end_selector = end_selector_cb ; + + /* + *Let's register our sac handler into the parser. + */ + cr_parser_set_sac_handler (parser, sac_handler) ; + + /* + *Now, let's do the parsing !!! + */ + cr_parser_parse (parser) ; + + /******************************************************* + *End of the parsing. A Couple of CSS rulesets must have + *been printed on the screen... + ***********************************************/ + + /* + *Time to free the resources we allocated. + */ + cr_parser_destroy (parser) ; + + return 0 ; +} diff --git a/src/3rdparty/libcroco/docs/examples/selection-example-1.c b/src/3rdparty/libcroco/docs/examples/selection-example-1.c new file mode 100644 index 0000000..3215a99 --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/selection-example-1.c @@ -0,0 +1,191 @@ +/** + * This example looks up a node from a document with an + * xpath expression, then reports all properties that apply + * from a given stylesheet. + * + * To compile it using gcc, type + * + * gcc -g -Wall `croco-0.6-config --cflags` `croco-0.6-config --libs` -o selection-example-1 selection-example-1.c + * + * Initial author: Stefan Seefeld. + */ + +#include <libcroco/libcroco.h> +#include <libcroco/cr-libxml-node-iface.h> +#include <libxml/tree.h> +#include <libxml/xpath.h> + +void +usage_and_exit (char *progname) +{ + fprintf (stderr, + "Usage: %s <xml doc> <stylesheet> <xpath>\n", + progname); + exit(-1); +} + +struct workspace +{ + xmlDoc *document; + xmlXPathContext *xpath; + xmlXPathObject *result; + CRStyleSheet *stylesheet; + CRCascade *cascade; + CRSelEng *selector; +}; + +/** + *construct workspace members in order... + * return 0 on success and -1 on error + */ +int +init (struct workspace *ws, char **args) +{ + enum CRStatus status = CR_OK; + + ws->document = 0; + ws->xpath = 0; + ws->result = 0; + ws->stylesheet = 0; + ws->cascade = 0; + ws->selector = 0; + + + ws->document = xmlParseFile(args[0]); + if (!ws->document) + { + fprintf(stderr, "could not parse the document %s", args[0]); + return -1; + } + ws->xpath = xmlXPathNewContext(ws->document); + if (!ws->xpath) + { + fprintf(stderr, "Error: unable to create new XPath context\n"); + return -1; + } + ws->result = xmlXPathEvalExpression((xmlChar *)args[2], ws->xpath); + if (!ws->result) + { + fprintf(stderr, "Error: unable to evaluate xpath expression\n"); + return -1; + } + if (ws->result->type != XPATH_NODESET || !ws->result->nodesetval) + { + fprintf(stderr, "Error: xpath does not evaluate to a node set\n"); + return -1; + } + + status = cr_om_parser_simply_parse_file((const guchar*)args[1] /*sheet*/, + CR_ASCII /*the encoding*/, + &ws->stylesheet); + if (status != CR_OK || !ws->stylesheet) + { + fprintf(stderr, "could not parse the stylesheet %s", args[1]); + return -1; + } + ws->cascade = cr_cascade_new(ws->stylesheet, 0, 0); + ws->selector = cr_sel_eng_new(&cr_libxml_node_iface); + return 1 ; +} + +/* ...and destruct in reverse order*/ +void +fini(struct workspace *ws) +{ + if (ws->selector) + { + cr_sel_eng_destroy(ws->selector); + ws->selector = NULL ; + } + if (ws->cascade) + { + cr_cascade_destroy(ws->cascade); + ws->cascade = NULL ; + } + + if (ws->result) + { + xmlXPathFreeObject(ws->result); + ws->result = NULL ; + } + if (ws->xpath) + { + xmlXPathFreeContext(ws->xpath); + ws->xpath = NULL ; + } + if (ws->document) + { + xmlFreeDoc(ws->document); + ws->document = NULL ; + } + xmlCleanupParser () ; +} + +void +print_properties_real (CRPropList *proplist) +{ + CRDeclaration *decl = NULL ; + CRPropList *cur_pair = NULL ; + + for (cur_pair = proplist ; cur_pair ; + cur_pair= cr_prop_list_get_next (cur_pair)) { + gchar *str = NULL ; + decl = NULL ; + + cr_prop_list_get_decl (cur_pair, &decl) ; + if (decl) { + str = cr_declaration_to_string (decl, 0) ; + if (str) { + printf ("%s\n", str) ; + g_free (str); + str = NULL ; + } + } + } +} + +void +print_properties (struct workspace *ws) +{ + enum CRStatus status; + CRPropList *prop_list = NULL; + xmlNode *node = ws->result->nodesetval->nodeTab[0]; + + status = cr_sel_eng_get_matched_properties_from_cascade + (ws->selector, ws->cascade, + node, &prop_list); + + if (status != CR_OK) + fprintf(stderr, "Error retrieving properties\n"); + else + { + xmlChar *prop = NULL ; + prop = xmlGetNodePath(node) ; + if (prop) { + printf("properties for node %s :\n", prop); + xmlFree (prop) ; + prop = NULL ; + } + print_properties_real (prop_list) ; + } + cr_prop_list_destroy (prop_list) ; +} + +int +main(int argc, char **argv) +{ + struct workspace ws; + if (argc != 4) usage_and_exit(argv[0]); + if (!init(&ws, argv + 1)) { + fini(&ws); + return -1 ; + } + + if (ws.result->nodesetval->nodeNr == 0) + printf("no matching nodes found\n"); + else + print_properties(&ws); + + fini(&ws); + return 0; +} diff --git a/src/3rdparty/libcroco/docs/examples/selection-example-1.css b/src/3rdparty/libcroco/docs/examples/selection-example-1.css new file mode 100644 index 0000000..044e053 --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/selection-example-1.css @@ -0,0 +1,41 @@ +report +{ + color : red; +} + +report > entry +{ + color : blue; +} + +note +{ + color : note-color; + frame : solid; +} + +note[id] +{ + color : note-id-color; + frame : solid; +} + +note[id=bar] +{ + margin : 5px; + color: note-id-bar-color ; +} + +note[id=foo] +{ + color : note-id-foo-color; +} + +entry[type=notice] note[id=bar] +{ + padding : 5px; +} + +note + notea { + color: notea-color ; +} diff --git a/src/3rdparty/libcroco/docs/examples/selection-example-1.xml b/src/3rdparty/libcroco/docs/examples/selection-example-1.xml new file mode 100644 index 0000000..4c3f558 --- /dev/null +++ b/src/3rdparty/libcroco/docs/examples/selection-example-1.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" ?> +<report> + <entry type="notice"> + <note id="foo"/> + <notea/> + <note id="bar"/> + </entry> + <entry> + <notea/> + <note/> + <note id="foo"/> + <note id="bar"/> + </entry> +</report> diff --git a/src/3rdparty/libcroco/docs/reference/Makefile.am b/src/3rdparty/libcroco/docs/reference/Makefile.am new file mode 100644 index 0000000..0ec463d --- /dev/null +++ b/src/3rdparty/libcroco/docs/reference/Makefile.am @@ -0,0 +1,53 @@ +## Process this file with automake to produce Makefile.in +NULL= + +# The name of the module, e.g. 'glib'. +DOC_MODULE=libcroco + +# The top-level SGML file. Change it if you want. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting functions and macros. +DOC_SOURCE_DIR=../../src + +# Extra options to pass to gtkdoc-scanobj or gtkdoc-scangobj. +SCANGOBJ_OPTIONS=--type-init-func="g_type_init()" + +# Extra options to supply to gtkdoc-scan. +SCAN_OPTIONS= + +# Extra options to supply to gtkdoc-mkdb. +MKDB_OPTIONS=--sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-fixref. +FIXXREF_OPTIONS= + +# Used for dependencies. +HFILE_GLOB=$(top_srcdir)/src/*.h +CFILE_GLOB=$(top_srcdir)/src/*.c + +# Header files to ignore when scanning. +IGNORE_HFILES=\ + $(NULL) + +# Images to copy into HTML directory. +HTML_IMAGES=\ + $(NULL) + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +content_files=\ + $(NULL) + +# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib +# contains GtkObjects/GObjects and you want to document signals and properties. +GTKDOC_CFLAGS=\ + $(CROCO_CFLAGS) \ + $(NULL) +GTKDOC_LIBS=\ + $(CROCO_LIBS) \ + $(NULL) + +include $(top_srcdir)/gtk-doc.make + diff --git a/src/3rdparty/libcroco/docs/reference/libcroco-docs.sgml b/src/3rdparty/libcroco/docs/reference/libcroco-docs.sgml new file mode 100644 index 0000000..f67e318 --- /dev/null +++ b/src/3rdparty/libcroco/docs/reference/libcroco-docs.sgml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> +<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude"> + <bookinfo> + <title>Libcroco Reference Manual</title> + </bookinfo> + + <chapter> + <title>Extensive APIs description</title> + <xi:include href="xml/cr-additional-sel.xml"/> + <xi:include href="xml/cr-attr-sel.xml"/> + <xi:include href="xml/cr-cascade.xml"/> + <xi:include href="xml/cr-declaration.xml"/> + <xi:include href="xml/cr-doc-handler.xml"/> + <xi:include href="xml/cr-enc-handler.xml"/> + <xi:include href="xml/cr-fonts.xml"/> + <xi:include href="xml/cr-input.xml"/> + <xi:include href="xml/cr-num.xml"/> + <xi:include href="xml/cr-om-parser.xml"/> + <xi:include href="xml/cr-parser.xml"/> + <xi:include href="xml/cr-parsing-location.xml"/> + <xi:include href="xml/cr-prop-list.xml"/> + <xi:include href="xml/cr-pseudo.xml"/> + <xi:include href="xml/cr-rgb.xml"/> + <xi:include href="xml/cr-sel-eng.xml"/> + <xi:include href="xml/cr-selector.xml"/> + <xi:include href="xml/cr-simple-sel.xml"/> + <xi:include href="xml/cr-statement.xml"/> + <xi:include href="xml/cr-string.xml"/> + <xi:include href="xml/cr-style.xml"/> + <xi:include href="xml/cr-stylesheet.xml"/> + <xi:include href="xml/cr-term.xml"/> + <xi:include href="xml/cr-tknzr.xml"/> + <xi:include href="xml/cr-token.xml"/> + <xi:include href="xml/cr-utils.xml"/> + <xi:include href="xml/libcroco-config.xml"/> + </chapter> +</book> diff --git a/src/3rdparty/libcroco/docs/release-notes-template.txt b/src/3rdparty/libcroco/docs/release-notes-template.txt new file mode 100644 index 0000000..df66f98 --- /dev/null +++ b/src/3rdparty/libcroco/docs/release-notes-template.txt @@ -0,0 +1,41 @@ +Application +=========== + +Libcroco 0.4 + +Description +=========== + +Libcroco is a CSS parsing and manipulation library +written in C for the gnome project. + +It provides : + +-two CSS parsing apis: SAC and CSSOM. +-A CSS2 selection and cascading engine based on libxml2. +-An experimental XML/CSS rendering engine. + +Changes +======= +- Removed the pango dependency from the + selection engine and put it in the layout engine. (Dodji Seketeli) +- Added a test example to demonstrate the use of the selection engine (Stefan Seefeld) + +Fixes +===== +- Fixed some gcc-2.96 parse errors (Dodji Seketeli) +- Make sure the header files are C++ friendly (Dodji Seketeli) +- Make sure the code examples compile with g++ (Dodji Seketeli) +- Fixed a bug in the selection engine (Dodji Seketeli) + +Homepage +======== +http://www.freespiders.org/projects/libcroco + +Download +======== +http://ftp.gnome.org/pub/GNOME/sources/libcroco + +GNOME Software Map entry +======================== +http://www.gnome.org/softwaremap/projects/libcroco diff --git a/src/3rdparty/libcroco/docs/usage.txt b/src/3rdparty/libcroco/docs/usage.txt new file mode 100644 index 0000000..a061116 --- /dev/null +++ b/src/3rdparty/libcroco/docs/usage.txt @@ -0,0 +1,47 @@ +initial author: Dodji Seketeli <dodji@seketeli.org> + +Note: +---- +Users can generate an html doc of all the functions of libcroco. +This is documentation is an unvaluable tool to master the libcroco +usage and internals. +To generate the documentation, just cd into the libcroco project +directory and type 'make apidoc' ; +This will generate the documentation in the docs/api directory. + + +Usage of the libcroco css2 parsing library +=========================================== + +libcroco has two main user programming interfaces: +the SAC parser, and the CSSOM parser. + + +The SAC parser +'''''''''''''''' + +The SAC (Simple Api for CSS) is the lowest level parsing api +provided by libcroco. +It is an event driven api in which the parser notifies the +caller whenever it encounters a remarquable css construction. + +The SAC parser is implemented in the CRParser class. +To use it, one must first instantiate a CRParser. + +I said earlier the the SAC parser notifies it caller +whenever it encounters certain css language constructions during +the parsing. "Notifies" actually means that it calls a subset of given +callback function pointers set. This set of function pointers is +called a "Document Handler". So, by overriding some function pointers +of the document handler, the user can define the actions to be +performed when a given css language construction is encountered. + +The SAC parser's api is defined in cr-parser.h and +the document handler's api is defined in cr-doc-handler.h . + + +The CSSOM parser +''''''''''''''''' + + + diff --git a/src/3rdparty/libcroco/global-test-vars.sh.in b/src/3rdparty/libcroco/global-test-vars.sh.in new file mode 100644 index 0000000..cfe1849 --- /dev/null +++ b/src/3rdparty/libcroco/global-test-vars.sh.in @@ -0,0 +1,12 @@ +TEST_OUT_DIR=./tests +TEST_SOURCE_DIR=@srcdir@/tests +TEST_INPUTS_DIR="$TEST_SOURCE_DIR"/test-inputs +CSSLINT=./csslint/.libs/csslint-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ +if ! test -x $CSSLINT ; then + echo "Error: Could not find an executable csslint. I was looking for $CSSLINT" >&2 + exit 1 +fi + +if ! test x"$VALGRIND" = x ; then + CSSLINT="$VALGRIND $CSSLINT" +fi diff --git a/src/3rdparty/libcroco/libcroco-indent b/src/3rdparty/libcroco/libcroco-indent new file mode 100755 index 0000000..f367987 --- /dev/null +++ b/src/3rdparty/libcroco/libcroco-indent @@ -0,0 +1,102 @@ +#!/bin/sh +#This is just a smallish indent script to indent mlview +#to indent all the sources correctly (before committing for ex), +#type: +#./indent-mlview src/*.[ch] + +#Here go some explanations of the indent options: +# +#-bad: forces a blank line after every block of declaration +#============================================================= +#-bap: forces a blank line after every procedure body +#============================================================= +#-bbb: forces a blank line before every boxed comment. +#============================================================= +#-sob: forces indent to swallow every optional blank line. +#============================================================= +#-bl -bli2 formats braces like this: +#if (x > 2) +# { +# x-- ; +# } +#============================================================= +#-nce formats the "else" not to cudle up to the +#immediately preceding }: +#if (x > 2) +# { +# x-- ; +# } +#else +# { +# x++ ; +# } +#============================== +#-ce is the contrary of -nce +#============================================================= +#-ss: put a space before a semi colon that is at the same line as a +#for. +#============================================================= +#-pcs: puts a space between the name of a procedure being called +#and the '('. +#============================================================= +#-bs: puts a space between the sizeof operator and its argument. +#============================================================= +#-saf: puts a space between a for an the following parenthesis. +#============================================================= +#-sai: puts a space between an if and its arguments +#============================================================= +#-saw: puts a space between a while and its arguments +#============================================================= +#-psl: causes the type of a procedure being defined to be placed +#on the line before the name of the procedure. +#============================================================= +#-bls: formats braces in struct declarations like this: +#struct foo +#{ +# int x; +#}; +#-brs: formats braces in struct decls like this: +#struct foo { +# int x; +#}; +#============================================================= +#-bc: forces a newline after each comma in a declaration. +#============================================================= +#-i2: puts indentation at 2 blank chars. +#============================================================= +#-lp: +#without -lp the code looks like this: +#p1 = first_procedure (second_procedure (p2, p3), +# third_procedure (p4, p5)); +#with -lp the code looks like this: +#p1 = first_procedure (second_procedure (p2, p3), +# third_procedure (p4, p5)); +#============================================================= +#-ppi2: indents preprocessor directives using 2 spaces. +#============================================================= +#============================================================= +#-ts2:set tabs spaces to 2 blank chars. +#============================================================= +#-l60 == --line-length60 +#============================================================= +#-bbo: break long lines before boolean operators when found. +#============================================================= + +INDENT=`which indent` +GREP=`which grep` +if test x$INDENT = x ; then + echo "Argh !!! Could not find indent in your PATH. Exited." + exit -1 + if test x$GREP = x ; then + echo "Argh!!! Could not find grep in you PATH. Exited." + exit -1 ; + fi + is_gnu=`$INDENT -version | $GREP gnu` + if test x$is_gnu = x ; then + echo "Found a indent that is not the GNU one. Exited." + exit -1 ; + fi +fi + +exec $INDENT -bad -bap -nbbb -br -ce -ss -pcs -bs -saf -sai \ +-cdw -saw -psl -brs -bc -i8 -ppi0 -lp -ts0 -bbo -sob $@ diff --git a/src/3rdparty/libcroco/libcroco-zip.in b/src/3rdparty/libcroco/libcroco-zip.in new file mode 100755 index 0000000..5b6e2ee --- /dev/null +++ b/src/3rdparty/libcroco/libcroco-zip.in @@ -0,0 +1,25 @@ +#!/bin/sh + +# Build distribution zipfiles for libcroco on Win32: Runtime and +# developer. + +ZIP=/tmp/libcroco-@VERSION@.zip +DEVZIP=/tmp/libcroco-dev-@VERSION@.zip + +# The DLL name generated by libtool with the passed --version-info +DLLNAME=libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@-`expr @LIBCROCO_CURRENT@ - @LIBCROCO_AGE@`.dll + +cd @prefix@ +rm $ZIP + +zip $ZIP -@ <<EOF +bin/$DLLNAME +EOF + +rm $DEVZIP +zip -r $DEVZIP -@ <<EOF +bin/csslint-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@.exe +include/libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ +lib/libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@.dll.a +lib/pkgconfig/libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@.pc +EOF diff --git a/src/3rdparty/libcroco/libcroco.doap b/src/3rdparty/libcroco/libcroco.doap new file mode 100644 index 0000000..4ffc1c6 --- /dev/null +++ b/src/3rdparty/libcroco/libcroco.doap @@ -0,0 +1,30 @@ +<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" + xmlns:foaf="http://xmlns.com/foaf/0.1/" + xmlns:gnome="http://api.gnome.org/doap-extensions#" + xmlns="http://usefulinc.com/ns/doap#"> + + <name xml:lang="en">libcroco</name> + <shortdesc xml:lang="en">A CSS parsing library</shortdesc> + <description>A CSS parsing library</description> + <homepage rdf:resource="http://www.linuxfromscratch.org/blfs/view/svn/general/libcroco.html" /> + <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/libcroco-list" /> + <download-page rdf:resource="https://download.gnome.org/sources/libcroco/" /> + <category rdf:resource="http://api.gnome.org/doap-extensions#core" /> + <programming-language>C</programming-language> + + <maintainer> + <foaf:Person> + <foaf:name>Abhishek Sharma</foaf:name> + <foaf:mbox rdf:resource="mailto:abhisheks@gnome.org" /> + <gnome:userid>abhisheks</gnome:userid> + </foaf:Person> + </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Dodji Seketeli</foaf:name> + <foaf:mbox rdf:resource="mailto:dodji@gnome.org" /> + <gnome:userid>dodji</gnome:userid> + </foaf:Person> + </maintainer> +</Project> diff --git a/src/3rdparty/libcroco/libcroco.pc.in b/src/3rdparty/libcroco/libcroco.pc.in new file mode 100644 index 0000000..3d0dc0a --- /dev/null +++ b/src/3rdparty/libcroco/libcroco.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libcroco +Version: @VERSION@ +Description: a CSS2 Parsing and manipulation Library in C. +Requires: glib-2.0 libxml-2.0 +Libs: -L${libdir} -lcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ +Cflags: -I${includedir}/libcroco-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ diff --git a/src/3rdparty/libcroco/libcroco.spec.in b/src/3rdparty/libcroco/libcroco.spec.in new file mode 100644 index 0000000..466d379 --- /dev/null +++ b/src/3rdparty/libcroco/libcroco.spec.in @@ -0,0 +1,82 @@ +%define lib_major 0 + +Name: libcroco +Summary: CSS2 parser library +Version: @VERSION@ +Release: 1 +License: LGPL +Group: System/Libraries +Source0: ftp://ftp.gnome.org/pub/GNOME/sources/%{name}-%{version}.tar.gz +URL: http://savannah.nongnu.org/projects/libcroco +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: libxml2-devel +BuildRequires: glib2-devel + +%description +libcroco is a standalone css2 parsing library. +It provides a low level event driven SAC like api +and a css object model like api. + +%package devel +Summary: Libraries and include files for developing with librsvg. +Group: Development/C +Requires: %{name} = %{version}-%{release} +Provides: %{name}-devel = %{version}-%{release} +Requires: libxml2-devel +Requires: glib2-devel + +%description devel +This package provides the necessary development libraries and include +files to allow you to develop with libcroco? + +%prep +%setup -q + +%build + +%configure + +make + +%install +[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT +%makeinstall + +%clean +[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT + + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-, root, root) +%doc AUTHORS COPYING COPYING.LIB ChangeLog NEWS README.md +%{_bindir}/csslint +%{_mandir}/man1/csslint* +%{_libdir}/*.so.* + +%files devel +%defattr(-,root,root) +%{_bindir}/croco-config +%{_mandir}/man1/croco-config* +%{_libdir}/*.la +%{_libdir}/*.a +%{_libdir}/*.so +%{_includedir}/* +%{_libdir}/pkgconfig/* + +%changelog +* Tue Jul 8 2003 Christian Schaller <Uraeus@gnome.org> +- Udate for 0.3 and Red Hat + +* Mon Jul 7 2003 Frederic Crozat <fcrozat@mandrakesoft.com> - 0.2.0-1mdk +- Release 0.2.0 +- WARNING : binary compat is broken, you need to recompile apps built with libcroco 0.1 + +* Fri Jun 13 2003 Gtz Waschk <waschk@linux-mandrake.com> 0.1.0-2mdk +- rebuild for new rpm + +* Fri Apr 18 2003 Frederic Crozat <fcrozat@mandrakesoft.com> - 0.1.0-1mdk +- First Mdk package. diff --git a/src/3rdparty/libcroco/src/CMakeLists.txt b/src/3rdparty/libcroco/src/CMakeLists.txt new file mode 100644 index 0000000..077c847 --- /dev/null +++ b/src/3rdparty/libcroco/src/CMakeLists.txt @@ -0,0 +1,85 @@ +set(G_DISABLE_CHECKS 0) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/libcroco-config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/libcroco-config.h") + +set(libcroco_headers + cr-additional-sel.h + cr-attr-sel.h + cr-cascade.h + cr-declaration.h + cr-doc-handler.h + cr-enc-handler.h + cr-fonts.h + cr-input.h + cr-libxml-node-iface.h + cr-node-iface.h + cr-num.h + cr-om-parser.h + cr-parser.h + cr-parsing-location.h + cr-prop-list.h + cr-pseudo.h + cr-rgb.h + cr-sel-eng.h + cr-selector.h + cr-simple-sel.h + cr-statement.h + cr-string.h + cr-style.h + cr-stylesheet.h + cr-term.h + cr-tknzr.h + cr-token.h + cr-utils.h + libcroco.h +) + +set(libcroco_SRC + cr-additional-sel.c + cr-attr-sel.c + cr-cascade.c + cr-declaration.c + cr-doc-handler.c + cr-enc-handler.c + cr-fonts.c + cr-input.c + cr-libxml-node-iface.c + cr-num.c + cr-om-parser.c + cr-parser.c + cr-parsing-location.c + cr-prop-list.c + cr-pseudo.c + cr-rgb.c + cr-selector.c + cr-sel-eng.c + cr-simple-sel.c + cr-statement.c + cr-string.c + cr-style.c + cr-stylesheet.c + cr-term.c + cr-tknzr.c + cr-token.c + cr-utils.c + ${libcroco_headers} +) + +add_library(croco_LIB STATIC "${libcroco_SRC}") + +target_include_directories(croco_LIB + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ${LIBXML_INCLUDE_DIRS} + PUBLIC + ${GLIB_INCLUDE_DIRS} +) + +target_link_libraries(croco_LIB + PRIVATE + ${GLIB_LDFLAGS} + INTERFACE + ${LIBXML_LDFLAGS} + m +) diff --git a/src/3rdparty/libcroco/src/Makefile.am b/src/3rdparty/libcroco/src/Makefile.am new file mode 100644 index 0000000..00711d4 --- /dev/null +++ b/src/3rdparty/libcroco/src/Makefile.am @@ -0,0 +1,136 @@ +NULL = + +lib_LTLIBRARIES=libcroco-0.6.la + +if PLATFORM_WIN32 +no_undefined = -no-undefined +endif + +#Headers files to be distributed +crocoincdir = $(includedir)/$(PACKAGE)-$(LIBCROCO_MAJOR_VERSION).$(LIBCROCO_MINOR_VERSION)/libcroco +crocoinc_HEADERS = \ + libcroco.h \ + cr-additional-sel.h \ + cr-attr-sel.h \ + cr-cascade.h \ + cr-declaration.h \ + cr-doc-handler.h \ + cr-enc-handler.h \ + cr-input.h \ + cr-libxml-node-iface.h \ + cr-num.h \ + cr-om-parser.h \ + cr-parser.h \ + cr-pseudo.h \ + cr-rgb.h \ + cr-selector.h \ + cr-simple-sel.h \ + cr-statement.h \ + cr-stylesheet.h \ + cr-term.h \ + cr-tknzr.h \ + cr-token.h \ + cr-utils.h \ + cr-fonts.h \ + cr-sel-eng.h \ + cr-style.h \ + cr-prop-list.h \ + cr-parsing-location.h \ + cr-string.h \ + libcroco-config.h \ + $(NULL) + +libcroco_0_6_la_SOURCES = \ + cr-utils.c \ + cr-utils.h \ + cr-input.c \ + cr-input.h \ + cr-enc-handler.c \ + cr-enc-handler.h \ + cr-libxml-node-iface.c \ + cr-node-iface.h \ + cr-num.c \ + cr-num.h \ + cr-rgb.c \ + cr-rgb.h \ + cr-token.c \ + cr-token.h \ + cr-tknzr.c \ + cr-tknzr.h \ + cr-term.c \ + cr-term.h \ + cr-attr-sel.c \ + cr-attr-sel.h \ + cr-pseudo.c \ + cr-pseudo.h \ + cr-additional-sel.c \ + cr-additional-sel.h \ + cr-simple-sel.c \ + cr-simple-sel.h \ + cr-selector.c \ + cr-selector.h \ + cr-doc-handler.c \ + cr-doc-handler.h \ + cr-parser.c \ + cr-parser.h \ + cr-declaration.c \ + cr-declaration.h \ + cr-statement.c \ + cr-statement.h \ + cr-stylesheet.c \ + cr-stylesheet.h \ + cr-cascade.c \ + cr-cascade.h \ + cr-om-parser.c \ + cr-om-parser.h \ + cr-style.c \ + cr-style.h \ + cr-sel-eng.c \ + cr-sel-eng.h \ + cr-fonts.c \ + cr-fonts.h \ + cr-prop-list.c \ + cr-prop-list.h \ + cr-parsing-location.c \ + cr-parsing-location.h \ + cr-string.c \ + cr-string.h \ + $(NULL) + +libcroco_0_6_la_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/intl \ + -I$(top_builddir)/src \ + $(AM_CPPFLAGS) + +libcroco_0_6_la_CFLAGS = \ + $(CROCO_CFLAGS) \ + $(AM_CFLAGS) + +libcroco_0_6_la_LDFLAGS = \ + -version-info @LIBCROCO_VERSION_INFO@ \ + $(no_undefined) \ + $(BSYMBOLIC_LDFLAG) \ + $(AM_LDFLAGS) + +libcroco_0_6_la_LIBADD = \ + $(CROCO_LIBS) + +EXTRA_DIST = libcroco.symbols + +# MSVC Build Items + +MSVCPROJS = croco + +croco_FILES = $(libcroco_0_6_la_SOURCES) +croco_EXCLUDES = dummy + +croco_HEADERS_DIR = $(crocoincdir) +croco_HEADERS_INST = $(crocoinc_HEADERS) +croco_HEADERS_EXCLUDES = dummy + +include $(top_srcdir)/win32/Makefile.msvcproj + +dist-hook: \ + $(top_builddir)/win32/vs9/croco.vcproj \ + $(top_builddir)/win32/vs9/croco.headers diff --git a/src/3rdparty/libcroco/src/cr-additional-sel.c b/src/3rdparty/libcroco/src/cr-additional-sel.c new file mode 100644 index 0000000..0296a6d --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-additional-sel.c @@ -0,0 +1,456 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + * + */ + +#include "cr-additional-sel.h" +#include "string.h" + +/** + * CRAdditionalSel: + * + * #CRAdditionalSel abstracts an additional selector. + * An additional selector is the selector part + * that comes after the combination of type selectors. + * It can be either "a class selector (the .class part), + * a pseudo class selector, an attribute selector + * or an id selector. + */ + +/** + * cr_additional_sel_new: + * + * Default constructor of #CRAdditionalSel. + * Returns the newly build instance of #CRAdditionalSel. + */ +CRAdditionalSel * +cr_additional_sel_new (void) +{ + CRAdditionalSel *result = NULL; + + result = g_try_malloc (sizeof (CRAdditionalSel)); + + if (result == NULL) { + cr_utils_trace_debug ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRAdditionalSel)); + + return result; +} + +/** + * cr_additional_sel_new_with_type: + * @a_sel_type: the type of the newly built instance + * of #CRAdditionalSel. + * + * Constructor of #CRAdditionalSel. + * Returns the newly built instance of #CRAdditionalSel. + */ +CRAdditionalSel * +cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type) +{ + CRAdditionalSel *result = NULL; + + result = cr_additional_sel_new (); + + g_return_val_if_fail (result, NULL); + + result->type = a_sel_type; + + return result; +} + +/** + * cr_additional_sel_set_class_name: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_class_name: the new class name to set. + * + * Sets a new class name to a + * CLASS additional selector. + */ +void +cr_additional_sel_set_class_name (CRAdditionalSel * a_this, + CRString * a_class_name) +{ + g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR); + + if (a_this->content.class_name) { + cr_string_destroy (a_this->content.class_name); + } + + a_this->content.class_name = a_class_name; +} + +/** + * cr_additional_sel_set_id_name: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_id: the new id to set. + * + * Sets a new id name to an + * ID additional selector. + */ +void +cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id) +{ + g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR); + + if (a_this->content.id_name) { + cr_string_destroy (a_this->content.id_name); + } + + a_this->content.id_name = a_id; +} + +/** + * cr_additional_sel_set_pseudo: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_pseudo: the new pseudo to set. + * + * Sets a new pseudo to a + * PSEUDO additional selector. + */ +void +cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo) +{ + g_return_if_fail (a_this + && a_this->type == PSEUDO_CLASS_ADD_SELECTOR); + + if (a_this->content.pseudo) { + cr_pseudo_destroy (a_this->content.pseudo); + } + + a_this->content.pseudo = a_pseudo; +} + +/** + * cr_additional_sel_set_attr_sel: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_sel: the new instance of #CRAttrSel to set. + * + * Sets a new instance of #CRAttrSel to + * a ATTRIBUTE additional selector. + */ +void +cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel) +{ + g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR); + + if (a_this->content.attr_sel) { + cr_attr_sel_destroy (a_this->content.attr_sel); + } + + a_this->content.attr_sel = a_sel; +} + +/** + * cr_additional_sel_append: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_sel: the new instance to #CRAdditional to append. + * + * Appends a new instance of #CRAdditional to the + * current list of #CRAdditional. + * + * Returns the new list of CRAdditionalSel or NULL if an error arises. + */ +CRAdditionalSel * +cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) +{ + CRAdditionalSel *cur_sel = NULL; + + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) { + return a_sel; + } + + if (a_sel == NULL) + return NULL; + + for (cur_sel = a_this; + cur_sel && cur_sel->next; cur_sel = cur_sel->next) ; + + g_return_val_if_fail (cur_sel != NULL, NULL); + + cur_sel->next = a_sel; + a_sel->prev = cur_sel; + + return a_this; +} + +/** + * cr_additional_sel_prepend: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * @a_sel: the new instance to #CRAdditional to preappend. + * + * Preppends a new instance of #CRAdditional to the + * current list of #CRAdditional. + * + * Returns the new list of CRAdditionalSel or NULL if an error arises. + */ +CRAdditionalSel * +cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) +{ + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) { + return a_sel; + } + + a_sel->next = a_this; + a_this->prev = a_sel; + + return a_sel; +} + +guchar * +cr_additional_sel_to_string (CRAdditionalSel const * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + CRAdditionalSel const *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + switch (cur->type) { + case CLASS_ADD_SELECTOR: + { + if (cur->content.class_name) { + g_string_append_printf + (str_buf, ".%s", + cur->content.class_name->stryng->str); + } + } + break; + + case ID_ADD_SELECTOR: + { + if (cur->content.id_name) { + g_string_append_printf + (str_buf, "#%s", + cur->content.id_name->stryng->str); + } + } + + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + { + if (cur->content.pseudo) { + guchar *tmp_str = NULL; + + tmp_str = cr_pseudo_to_string + (cur->content.pseudo); + if (tmp_str) { + g_string_append_printf + (str_buf, ":%s", + tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + break; + + case ATTRIBUTE_ADD_SELECTOR: + if (cur->content.attr_sel) { + guchar *tmp_str = NULL; + + g_string_append_c (str_buf, '['); + tmp_str = cr_attr_sel_to_string + (cur->content.attr_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s]", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + break; + + default: + break; + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +guchar * +cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL) ; + + str_buf = g_string_new (NULL) ; + + switch (a_this->type) { + case CLASS_ADD_SELECTOR: + if (a_this->content.class_name) { + g_string_append_printf + (str_buf, ".%s", + a_this->content.class_name->stryng->str); + } + break; + + case ID_ADD_SELECTOR: + if (a_this->content.id_name) { + g_string_append_printf + (str_buf, "#%s", + a_this->content.id_name->stryng->str); + } + + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + { + if (a_this->content.pseudo) { + guchar *tmp_str = NULL; + + tmp_str = cr_pseudo_to_string + (a_this->content.pseudo); + if (tmp_str) { + g_string_append_printf + (str_buf, ":%s", + tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + break; + + case ATTRIBUTE_ADD_SELECTOR: + if (a_this->content.attr_sel) { + guchar *tmp_str = NULL; + + g_string_append_printf (str_buf, "["); + tmp_str = cr_attr_sel_to_string + (a_this->content.attr_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s]", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + break; + + default: + break; + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + * cr_additional_sel_dump: + * @a_this: the "this pointer" of the current instance of + * #CRAdditionalSel. + * @a_fp: the destination file. + * + * Dumps the current instance of #CRAdditionalSel to a file + */ +void +cr_additional_sel_dump (CRAdditionalSel const * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_if_fail (a_fp); + + if (a_this) { + tmp_str = cr_additional_sel_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } +} + +/** + * cr_additional_sel_destroy: + * @a_this: the "this pointer" of the current instance + * of #CRAdditionalSel . + * + * Destroys an instance of #CRAdditional. + */ +void +cr_additional_sel_destroy (CRAdditionalSel * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case CLASS_ADD_SELECTOR: + cr_string_destroy (a_this->content.class_name); + a_this->content.class_name = NULL; + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + cr_pseudo_destroy (a_this->content.pseudo); + a_this->content.pseudo = NULL; + break; + + case ID_ADD_SELECTOR: + cr_string_destroy (a_this->content.id_name); + a_this->content.id_name = NULL; + break; + + case ATTRIBUTE_ADD_SELECTOR: + cr_attr_sel_destroy (a_this->content.attr_sel); + a_this->content.attr_sel = NULL; + break; + + default: + break; + } + + if (a_this->next) { + cr_additional_sel_destroy (a_this->next); + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-additional-sel.h b/src/3rdparty/libcroco/src/cr-additional-sel.h new file mode 100644 index 0000000..7ca3e07 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-additional-sel.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyright information. + */ + + +#ifndef __CR_ADD_SEL_H__ +#define __CR_ADD_SEL_H__ + +#include <stdio.h> +#include <glib.h> +#include "cr-utils.h" +#include "cr-attr-sel.h" +#include "cr-pseudo.h" +#include "cr-additional-sel.h" + +G_BEGIN_DECLS + +enum AddSelectorType +{ + NO_ADD_SELECTOR = 0 , + CLASS_ADD_SELECTOR = 1 , + PSEUDO_CLASS_ADD_SELECTOR = 1 << 1, + ID_ADD_SELECTOR = 1 << 3, + ATTRIBUTE_ADD_SELECTOR = 1 << 4 +} ; + +union CRAdditionalSelectorContent +{ + CRString *class_name ; + CRString *id_name ; + CRPseudo *pseudo ; + CRAttrSel *attr_sel ; +} ; + +typedef struct _CRAdditionalSel CRAdditionalSel ; + +struct _CRAdditionalSel +{ + enum AddSelectorType type ; + union CRAdditionalSelectorContent content ; + + CRAdditionalSel * next ; + CRAdditionalSel * prev ; + CRParsingLocation location ; +} ; + +CRAdditionalSel * cr_additional_sel_new (void) ; + +CRAdditionalSel * cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type) ; + +CRAdditionalSel * cr_additional_sel_append (CRAdditionalSel *a_this, + CRAdditionalSel *a_sel) ; + +void cr_additional_sel_set_class_name (CRAdditionalSel *a_this, + CRString *a_class_name) ; + +void cr_additional_sel_set_id_name (CRAdditionalSel *a_this, + CRString *a_id) ; + +void cr_additional_sel_set_pseudo (CRAdditionalSel *a_this, + CRPseudo *a_pseudo) ; + +void cr_additional_sel_set_attr_sel (CRAdditionalSel *a_this, + CRAttrSel *a_sel) ; + +CRAdditionalSel * cr_additional_sel_prepend (CRAdditionalSel *a_this, + CRAdditionalSel *a_sel) ; + +guchar * cr_additional_sel_to_string (CRAdditionalSel const *a_this) ; + +guchar * cr_additional_sel_one_to_string (CRAdditionalSel const *a_this) ; + +void cr_additional_sel_dump (CRAdditionalSel const *a_this, FILE *a_fp) ; + +void cr_additional_sel_destroy (CRAdditionalSel *a_this) ; + +G_END_DECLS + +#endif /*__CR_ADD_SEL_H*/ diff --git a/src/3rdparty/libcroco/src/cr-attr-sel.c b/src/3rdparty/libcroco/src/cr-attr-sel.c new file mode 100644 index 0000000..b4c64c3 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-attr-sel.c @@ -0,0 +1,221 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyrights information. + */ + +#include <stdio.h> +#include "cr-attr-sel.h" + +/** + * CRAttrSel: + * + * #CRAdditionalSel abstracts an attribute selector. + * Attributes selectors are described in the css2 spec [5.8]. + * There are more generally used in the css2 selectors described in + * css2 spec [5] . + */ + +/** + * cr_attr_sel_new: + * The constructor of #CRAttrSel. + * Returns the newly allocated instance + * of #CRAttrSel. + */ +CRAttrSel * +cr_attr_sel_new (void) +{ + CRAttrSel *result = NULL; + + result = g_malloc0 (sizeof (CRAttrSel)); + + return result; +} + +/** + * cr_attr_sel_append_attr_sel: + * @a_this: the this pointer of the current instance of #CRAttrSel. + * @a_attr_sel: selector to append. + * + * Appends an attribute selector to the current list of + * attribute selectors represented by a_this. + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_attr_sel_append_attr_sel (CRAttrSel * a_this, CRAttrSel * a_attr_sel) +{ + CRAttrSel *cur_sel = NULL; + + g_return_val_if_fail (a_this && a_attr_sel, + CR_BAD_PARAM_ERROR); + + for (cur_sel = a_this; + cur_sel->next; + cur_sel = cur_sel->next) ; + + cur_sel->next = a_attr_sel; + a_attr_sel->prev = cur_sel; + + return CR_OK; +} + +/** + * cr_attr_sel_prepend_attr_sel: + *@a_this: the "this pointer" of the current instance *of #CRAttrSel. + *@a_attr_sel: the attribute selector to append. + * + *Prepends an attribute selector to the list of + *attributes selector represented by a_this. + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_attr_sel_prepend_attr_sel (CRAttrSel * a_this, + CRAttrSel * a_attr_sel) +{ + g_return_val_if_fail (a_this && a_attr_sel, + CR_BAD_PARAM_ERROR); + + a_attr_sel->next = a_this; + a_this->prev = a_attr_sel; + + return CR_OK; +} + +/** + * cr_attr_sel_to_string: + * @a_this: the current instance of #CRAttrSel. + * + * Serializes an attribute selector into a string + * Returns the serialized attribute selector. + */ +guchar * +cr_attr_sel_to_string (CRAttrSel const * a_this) +{ + CRAttrSel const *cur = NULL; + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->prev) { + g_string_append_c (str_buf, ' '); + } + + if (cur->name) { + gchar const *name = cur->name->stryng->str; + if (name) { + g_string_append (str_buf, (const gchar *) name); + } + } + + if (cur->value) { + gchar const *value = cur->value->stryng->str; + if (value) { + switch (cur->match_way) { + case SET: + break; + + case EQUALS: + g_string_append_c (str_buf, '='); + break; + + case INCLUDES: + g_string_append (str_buf, "~="); + break; + + case DASHMATCH: + g_string_append (str_buf, "|="); + break; + + default: + break; + } + + g_string_append_printf + (str_buf, "\"%s\"", value); + } + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + } + + return result; +} + +/** + * cr_attr_sel_dump: + * @a_this: the "this pointer" of the current instance of + * #CRAttrSel. + * @a_fp: the destination file. + * + * Dumps the current instance of #CRAttrSel to a file. + */ +void +cr_attr_sel_dump (CRAttrSel const * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_if_fail (a_this); + + tmp_str = cr_attr_sel_to_string (a_this); + + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } +} + +/** + *cr_attr_sel_destroy: + *@a_this: the "this pointer" of the current + *instance of #CRAttrSel. + * + *Destroys the current instance of #CRAttrSel. + *Frees all the fields if they are non null. + */ +void +cr_attr_sel_destroy (CRAttrSel * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->value) { + cr_string_destroy (a_this->value); + a_this->value = NULL; + } + + if (a_this->next) { + cr_attr_sel_destroy (a_this->next); + a_this->next = NULL; + } + + g_free (a_this); +} + diff --git a/src/3rdparty/libcroco/src/cr-attr-sel.h b/src/3rdparty/libcroco/src/cr-attr-sel.h new file mode 100644 index 0000000..82d5a87 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-attr-sel.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_ATTR_SEL_H__ +#define __CR_ATTR_SEL_H__ + +#include <stdio.h> +#include <glib.h> +#include "cr-utils.h" +#include "cr-parsing-location.h" +#include "cr-string.h" + +G_BEGIN_DECLS + + +struct _CRAttrSel ; +typedef struct _CRAttrSel CRAttrSel ; + +enum AttrMatchWay +{ + NO_MATCH = 0, + SET, + EQUALS, + INCLUDES, + DASHMATCH +} ; + +struct _CRAttrSel +{ + CRString *name ; + CRString *value ; + enum AttrMatchWay match_way ; + CRAttrSel *next ; + CRAttrSel *prev ; + CRParsingLocation location ; +} ; + +CRAttrSel * cr_attr_sel_new (void) ; + +enum CRStatus cr_attr_sel_append_attr_sel (CRAttrSel * a_this, + CRAttrSel *a_attr_sel) ; + +enum CRStatus cr_attr_sel_prepend_attr_sel (CRAttrSel *a_this, + CRAttrSel *a_attr_sel) ; + +guchar * cr_attr_sel_to_string (CRAttrSel const *a_this) ; + +void cr_attr_sel_dump (CRAttrSel const *a_this, FILE *a_fp) ; + +void cr_attr_sel_destroy (CRAttrSel *a_this) ; + +G_END_DECLS + +#endif /*__CR_ATTR_SEL_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-cascade.c b/src/3rdparty/libcroco/src/cr-cascade.c new file mode 100644 index 0000000..3f32a51 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-cascade.c @@ -0,0 +1,214 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +#include <string.h> +#include "cr-cascade.h" + +#define PRIVATE(a_this) ((a_this)->priv) + +struct _CRCascadePriv { + /** + *the 3 style sheets of the cascade: + *author, user, and useragent sheet. + *Intended to be addressed by + *sheets[ORIGIN_AUTHOR] or sheets[ORIGIN_USER] + *of sheets[ORIGIN_UA] ; + */ + CRStyleSheet *sheets[3]; + guint ref_count; +}; + +/** + * cr_cascade_new: + *@a_author_sheet: the author origin style sheet. May be NULL. + *@a_user_sheet: the user origin style sheet. May be NULL. + *@a_ua_sheet: the user agent origin style sheet. May be NULL. + * + *Constructor of the #CRCascade class. + *Note that all three parameters of this + *method are ref counted and their refcount is increased. + *Their refcount will be decreased at the destruction of + *the instance of #CRCascade. + *So the caller should not call their destructor. The caller + *should call their ref/unref method instead if it wants + * + *Returns the newly built instance of CRCascade or NULL if + *an error arose during construction. + */ +CRCascade * +cr_cascade_new (CRStyleSheet * a_author_sheet, + CRStyleSheet * a_user_sheet, CRStyleSheet * a_ua_sheet) +{ + CRCascade *result = NULL; + + result = g_try_malloc (sizeof (CRCascade)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRCascade)); + + PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); + + if (a_author_sheet) { + cr_cascade_set_sheet (result, a_author_sheet, ORIGIN_AUTHOR); + } + if (a_user_sheet) { + cr_cascade_set_sheet (result, a_user_sheet, ORIGIN_USER); + } + if (a_ua_sheet) { + cr_cascade_set_sheet (result, a_ua_sheet, ORIGIN_UA); + } + + return result; +} + +/** + * cr_cascade_get_sheet: + *@a_this: the current instance of #CRCascade. + *@a_origin: the origin of the style sheet as + *defined in the css2 spec in chapter 6.4. + *Gets a given origin sheet. + * + *Gets a sheet, part of the cascade. + *Note that the returned stylesheet + *is refcounted so if the caller wants + *to manage its lifecycle, it must use + *cr_stylesheet_ref()/cr_stylesheet_unref() instead + *of the cr_stylesheet_destroy() method. + *Returns the style sheet, or NULL if it does not + *exist. + */ +CRStyleSheet * +cr_cascade_get_sheet (CRCascade * a_this, enum CRStyleOrigin a_origin) +{ + g_return_val_if_fail (a_this + && (unsigned)a_origin < NB_ORIGINS, NULL); + + return PRIVATE (a_this)->sheets[a_origin]; +} + +/** + * cr_cascade_set_sheet: + *@a_this: the current instance of #CRCascade. + *@a_sheet: the stylesheet to set. May be NULL. + *@a_origin: the origin of the stylesheet. + * + *Sets a stylesheet in the cascade + * + *Returns CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_cascade_set_sheet (CRCascade * a_this, + CRStyleSheet * a_sheet, enum CRStyleOrigin a_origin) +{ + g_return_val_if_fail (a_this + && (unsigned)a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->sheets[a_origin]) + cr_stylesheet_unref (PRIVATE (a_this)->sheets[a_origin]); + PRIVATE (a_this)->sheets[a_origin] = a_sheet; + if (a_sheet) { + cr_stylesheet_ref (a_sheet); + a_sheet->origin = a_origin; + } + return CR_OK; +} + +/** + *cr_cascade_ref: + *@a_this: the current instance of #CRCascade + * + *Increases the reference counter of the current instance + *of #CRCascade. + */ +void +cr_cascade_ref (CRCascade * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +/** + * cr_cascade_unref: + *@a_this: the current instance of + *#CRCascade. + * + *Decrements the reference counter associated + *to this instance of #CRCascade. If the reference + *counter reaches zero, the instance is destroyed + *using cr_cascade_destroy() + */ +void +cr_cascade_unref (CRCascade * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->ref_count) + PRIVATE (a_this)->ref_count--; + if (!PRIVATE (a_this)->ref_count) { + cr_cascade_destroy (a_this); + } +} + +/** + * cr_cascade_destroy: + * @a_this: the current instance of #CRCascade + * + * Destructor of #CRCascade. + */ +void +cr_cascade_destroy (CRCascade * a_this) +{ + g_return_if_fail (a_this); + + if (PRIVATE (a_this)) { + gulong i = 0; + + for (i = 0; i < NB_ORIGINS; i++) { + if (PRIVATE (a_this)->sheets[i]) { + if (cr_stylesheet_unref + (PRIVATE (a_this)->sheets[i]) + == TRUE) { + PRIVATE (a_this)->sheets[i] = NULL; + } + } + } + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-cascade.h b/src/3rdparty/libcroco/src/cr-cascade.h new file mode 100644 index 0000000..3119ae8 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-cascade.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +/* + *$Id$ + */ + +#ifndef __CR_CASCADE_H__ +#define __CR_CASCADE_H__ + +#include "cr-stylesheet.h" + +/** + *@file + *the declaration of the #CRCascade class. + */ + +G_BEGIN_DECLS + + +typedef struct _CRCascadePriv CRCascadePriv ; + +/** + *An abstraction of the "Cascade" defined + *in the css2 spec, chapter 6.4. + */ +typedef struct _CRCascade CRCascade ; + +struct _CRCascade +{ + CRCascadePriv *priv ; +}; + + +CRCascade * cr_cascade_new (CRStyleSheet *a_author_sheet, + CRStyleSheet *a_user_sheet, + CRStyleSheet *a_ua_sheet) ; + +CRStyleSheet * cr_cascade_get_sheet (CRCascade *a_this, + enum CRStyleOrigin a_origin) ; + +enum CRStatus cr_cascade_set_sheet (CRCascade *a_this, + CRStyleSheet *a_sheet, + enum CRStyleOrigin a_origin) ; + +void cr_cascade_ref (CRCascade *a_this) ; + +void cr_cascade_unref (CRCascade *a_this) ; + +void cr_cascade_destroy (CRCascade *a_this) ; + +G_END_DECLS + +#endif /*__CR_CASCADE_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-declaration.c b/src/3rdparty/libcroco/src/cr-declaration.c new file mode 100644 index 0000000..f998a2a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-declaration.c @@ -0,0 +1,794 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + + +#include <string.h> +#include "cr-declaration.h" +#include "cr-statement.h" +#include "cr-parser.h" + +/** + *@CRDeclaration: + * + *The definition of the #CRDeclaration class. + */ + +/** + * dump: + *@a_this: the current instance of #CRDeclaration. + *@a_fp: the destination file pointer. + *@a_indent: the number of indentation white char. + * + *Dumps (serializes) one css declaration to a file. + */ +static void +dump (CRDeclaration const * a_this, FILE * a_fp, glong a_indent) +{ + guchar *str = NULL; + + g_return_if_fail (a_this); + + str = (guchar *) cr_declaration_to_string (a_this, a_indent); + if (str) { + fprintf (a_fp, "%s", str); + g_free (str); + str = NULL; + } +} + +/** + * cr_declaration_new: + * @a_statement: the statement this declaration belongs to. can be NULL. + *@a_property: the property string of the declaration + *@a_value: the value expression of the declaration. + *Constructor of #CRDeclaration. + * + *Returns the newly built instance of #CRDeclaration, or NULL in + *case of error. + * + *The returned CRDeclaration takes ownership of @a_property and @a_value. + *(E.g. cr_declaration_destroy on this CRDeclaration will also free + *@a_property and @a_value.) + */ +CRDeclaration * +cr_declaration_new (CRStatement * a_statement, + CRString * a_property, CRTerm * a_value) +{ + CRDeclaration *result = NULL; + + g_return_val_if_fail (a_property, NULL); + + if (a_statement) + g_return_val_if_fail (a_statement + && ((a_statement->type == RULESET_STMT) + || (a_statement->type + == AT_FONT_FACE_RULE_STMT) + || (a_statement->type + == AT_PAGE_RULE_STMT)), NULL); + + result = g_try_malloc (sizeof (CRDeclaration)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRDeclaration)); + result->property = a_property; + result->value = a_value; + + if (a_value) { + cr_term_ref (a_value); + } + result->parent_statement = a_statement; + return result; +} + +/** + * cr_declaration_parse_from_buf: + *@a_statement: the parent css2 statement of this + *this declaration. Must be non NULL and of type + *RULESET_STMT (must be a ruleset). + *@a_str: the string that contains the statement. + *@a_enc: the encoding of a_str. + * + *Parses a text buffer that contains + *a css declaration. + *Returns the parsed declaration, or NULL in case of error. + */ +CRDeclaration * +cr_declaration_parse_from_buf (CRStatement * a_statement, + const guchar * a_str, enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK; + CRTerm *value = NULL; + CRString *property = NULL; + CRDeclaration *result = NULL; + CRParser *parser = NULL; + gboolean important = FALSE; + + g_return_val_if_fail (a_str, NULL); + if (a_statement) + g_return_val_if_fail (a_statement->type == RULESET_STMT, + NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen ((const char *) a_str), a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_declaration (parser, &property, + &value, &important); + if (status != CR_OK || !property) + goto cleanup; + + result = cr_declaration_new (a_statement, property, value); + if (result) { + property = NULL; + value = NULL; + result->important = important; + } + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + if (property) { + cr_string_destroy (property); + property = NULL; + } + + if (value) { + cr_term_destroy (value); + value = NULL; + } + + return result; +} + +/** + * cr_declaration_parse_list_from_buf: + *@a_str: the input buffer that contains the list of declaration to + *parse. + *@a_enc: the encoding of a_str + * + *Parses a ';' separated list of properties declaration. + *Returns the parsed list of declaration, NULL if parsing failed. + */ +CRDeclaration * +cr_declaration_parse_list_from_buf (const guchar * a_str, + enum CREncoding a_enc) +{ + + enum CRStatus status = CR_OK; + CRTerm *value = NULL; + CRString *property = NULL; + CRDeclaration *result = NULL, + *cur_decl = NULL; + CRParser *parser = NULL; + CRTknzr *tokenizer = NULL; + gboolean important = FALSE; + gboolean first = TRUE; + + g_return_val_if_fail (a_str, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen ((const char *) a_str), a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + status = cr_parser_get_tknzr (parser, &tokenizer); + if (status != CR_OK || !tokenizer) { + if (status == CR_OK) + status = CR_ERROR; + goto cleanup; + } + + for (;; first = FALSE) { + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + if (!first) { + guint32 c = 0; + + status = cr_tknzr_peek_char (tokenizer, &c); + if (status != CR_OK) { + goto cleanup; + } + if (c == ';') { + status = cr_tknzr_read_char (tokenizer, &c); + } else { + cr_tknzr_read_char (tokenizer, &c); + continue; // try to keep reading until we reach the end or a ; + } + important = FALSE; + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + } + + status = cr_parser_parse_declaration (parser, &property, + &value, &important); + if (status != CR_OK || !property) { + if (status == CR_END_OF_INPUT_ERROR) { + break; + } else { + continue; // even if one declaration is broken, it's no reason to discard others (see http://www.w3.org/TR/CSS21/syndata.html#declaration) + } + } + cur_decl = cr_declaration_new (NULL, property, value); + if (cur_decl) { + cur_decl->important = important; + if (result) { + result = cr_declaration_append (result, cur_decl); + } else { + result = cur_decl; + } + property = NULL; + value = NULL; + cur_decl = NULL; + } else { + break; + } + } + + cleanup: + + if (status == CR_END_OF_INPUT_ERROR && result) { + status = CR_OK; + } + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + if (property) { + cr_string_destroy (property); + property = NULL; + } + + if (value) { + cr_term_destroy (value); + value = NULL; + } + + if (status != CR_OK && result) { + cr_declaration_destroy (result); + result = NULL; + } + return result; +} + +/** + * cr_declaration_append: + *@a_this: the current declaration list. + *@a_new: the declaration to append. + * + *Appends a new declaration to the current declarations list. + *Returns the declaration list with a_new appended to it, or NULL + *in case of error. + */ +CRDeclaration * +cr_declaration_append (CRDeclaration * a_this, CRDeclaration * a_new) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + * cr_declaration_unlink: + *@a_decls: the declaration to unlink. + * + *Unlinks the declaration from the declaration list. + *case of a successful completion, NULL otherwise. + * + *Returns a pointer to the unlinked declaration in + */ +CRDeclaration * +cr_declaration_unlink (CRDeclaration * a_decl) +{ + CRDeclaration *result = a_decl; + + g_return_val_if_fail (result, NULL); + + /* + *some sanity checks first + */ + if (a_decl->prev) { + g_return_val_if_fail (a_decl->prev->next == a_decl, NULL); + + } + if (a_decl->next) { + g_return_val_if_fail (a_decl->next->prev == a_decl, NULL); + } + + /* + *now, the real unlinking job. + */ + if (a_decl->prev) { + a_decl->prev->next = a_decl->next; + } + if (a_decl->next) { + a_decl->next->prev = a_decl->prev; + } + if (a_decl->parent_statement) { + CRDeclaration **children_decl_ptr = NULL; + + switch (a_decl->parent_statement->type) { + case RULESET_STMT: + if (a_decl->parent_statement->kind.ruleset) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.ruleset->decl_list; + } + + break; + + case AT_FONT_FACE_RULE_STMT: + if (a_decl->parent_statement->kind.font_face_rule) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.font_face_rule->decl_list; + } + break; + case AT_PAGE_RULE_STMT: + if (a_decl->parent_statement->kind.page_rule) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.page_rule->decl_list; + } + + default: + break; + } + if (children_decl_ptr + && *children_decl_ptr && *children_decl_ptr == a_decl) + *children_decl_ptr = (*children_decl_ptr)->next; + } + + a_decl->next = NULL; + a_decl->prev = NULL; + a_decl->parent_statement = NULL; + + return result; +} + +/** + * cr_declaration_prepend: + * @a_this: the current declaration list. + * @a_new: the declaration to prepend. + * + * prepends a declaration to the current declaration list. + * + * Returns the list with a_new prepended or NULL in case of error. + */ +CRDeclaration * +cr_declaration_prepend (CRDeclaration * a_this, CRDeclaration * a_new) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + a_this->prev = a_new; + a_new->next = a_this; + + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + * cr_declaration_append2: + *@a_this: the current declaration list. + *@a_prop: the property string of the declaration to append. + *@a_value: the value of the declaration to append. + * + *Appends a declaration to the current declaration list. + *Returns the list with the new property appended to it, or NULL in + *case of an error. + */ +CRDeclaration * +cr_declaration_append2 (CRDeclaration * a_this, + CRString * a_prop, CRTerm * a_value) +{ + CRDeclaration *new_elem = NULL; + + if (a_this) { + new_elem = cr_declaration_new (a_this->parent_statement, + a_prop, a_value); + } else { + new_elem = cr_declaration_new (NULL, a_prop, a_value); + } + + g_return_val_if_fail (new_elem, NULL); + + return cr_declaration_append (a_this, new_elem); +} + +/** + * cr_declaration_dump: + *@a_this: the current instance of #CRDeclaration. + *@a_fp: the destination file. + *@a_indent: the number of indentation white char. + *@a_one_per_line: whether to put one declaration per line of not . + * + * + *Dumps a declaration list to a file. + */ +void +cr_declaration_dump (CRDeclaration const * a_this, FILE * a_fp, glong a_indent, + gboolean a_one_per_line) +{ + CRDeclaration const *cur = NULL; + + g_return_if_fail (a_this); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->prev) { + if (a_one_per_line == TRUE) + fprintf (a_fp, ";\n"); + else + fprintf (a_fp, "; "); + } + dump (cur, a_fp, a_indent); + } +} + +/** + * cr_declaration_dump_one: + *@a_this: the current instance of #CRDeclaration. + *@a_fp: the destination file. + *@a_indent: the number of indentation white char. + * + *Dumps the first declaration of the declaration list to a file. + */ +void +cr_declaration_dump_one (CRDeclaration const * a_this, FILE * a_fp, glong a_indent) +{ + g_return_if_fail (a_this); + + dump (a_this, a_fp, a_indent); +} + +/** + * cr_declaration_to_string: + *@a_this: the current instance of #CRDeclaration. + *@a_indent: the number of indentation white char + *to put before the actual serialisation. + * + *Serializes the declaration into a string + *Returns the serialized form the declaration. The caller must + *free the string using g_free(). + */ +gchar * +cr_declaration_to_string (CRDeclaration const * a_this, gulong a_indent) +{ + GString *stringue = NULL; + + gchar *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + if (a_this->property + && a_this->property->stryng + && a_this->property->stryng->str) { + gchar const *str = a_this->property->stryng->str; + if (str) { + cr_utils_dump_n_chars2 (' ', stringue, + a_indent); + g_string_append (stringue, str); + } else + goto error; + + if (a_this->value) { + guchar *value_str = NULL; + + value_str = cr_term_to_string (a_this->value); + if (value_str) { + g_string_append_printf (stringue, " : %s", + value_str); + g_free (value_str); + } else + goto error; + } + if (a_this->important == TRUE) { + g_string_append_printf (stringue, " %s", + "!important"); + } + } + if (stringue && stringue->str) { + result = stringue->str; + g_string_free (stringue, FALSE); + } + return result; + + error: + if (stringue) { + g_string_free (stringue, TRUE); + stringue = NULL; + } + + return result; +} + +/** + * cr_declaration_list_to_string: + *@a_this: the current instance of #CRDeclaration. + *@a_indent: the number of indentation white char + *to put before the actual serialisation. + * + *Serializes the declaration list into a string + */ +guchar * +cr_declaration_list_to_string (CRDeclaration const * a_this, gulong a_indent) +{ + CRDeclaration const *cur = NULL; + GString *stringue = NULL; + guchar *str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + str = (guchar *) cr_declaration_to_string (cur, a_indent); + if (str) { + g_string_append_printf (stringue, "%s;", str); + g_free (str); + } else + break; + } + if (stringue && stringue->str) { + result = (guchar *) stringue->str; + g_string_free (stringue, FALSE); + } + + return result; +} + +/** + * cr_declaration_list_to_string2: + *@a_this: the current instance of #CRDeclaration. + *@a_indent: the number of indentation white char + *@a_one_decl_per_line: whether to output one doc per line or not. + *to put before the actual serialisation. + * + *Serializes the declaration list into a string + *Returns the serialized form the declararation. + */ +guchar * +cr_declaration_list_to_string2 (CRDeclaration const * a_this, + gulong a_indent, gboolean a_one_decl_per_line) +{ + CRDeclaration const *cur = NULL; + GString *stringue = NULL; + guchar *str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + str = (guchar *) cr_declaration_to_string (cur, a_indent); + if (str) { + if (a_one_decl_per_line == TRUE) { + if (cur->next) + g_string_append_printf (stringue, + "%s;\n", str); + else + g_string_append (stringue, + (const gchar *) str); + } else { + if (cur->next) + g_string_append_printf (stringue, + "%s;", str); + else + g_string_append (stringue, + (const gchar *) str); + } + g_free (str); + } else + break; + } + if (stringue && stringue->str) { + result = (guchar *) stringue->str; + g_string_free (stringue, FALSE); + } + + return result; +} + +/** + * cr_declaration_nr_props: + *@a_this: the current instance of #CRDeclaration. + *Return the number of properties in the declaration + */ +gint +cr_declaration_nr_props (CRDeclaration const * a_this) +{ + CRDeclaration const *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, -1); + + for (cur = a_this; cur; cur = cur->next) + nr++; + return nr; +} + +/** + * cr_declaration_get_from_list: + *@a_this: the current instance of #CRDeclaration. + *@itemnr: the index into the declaration list. + * + *Use an index to get a CRDeclaration from the declaration list. + * + *Returns #CRDeclaration at position itemnr, + *if itemnr > number of declarations - 1, + *it will return NULL. + */ +CRDeclaration * +cr_declaration_get_from_list (CRDeclaration * a_this, int itemnr) +{ + CRDeclaration *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, NULL); + + for (cur = a_this; cur; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + * cr_declaration_get_by_prop_name: + *@a_this: the current instance of #CRDeclaration. + *@a_prop: the property name to search for. + * + *Use property name to get a CRDeclaration from the declaration list. + *Returns #CRDeclaration with property name a_prop, or NULL if not found. + */ +CRDeclaration * +cr_declaration_get_by_prop_name (CRDeclaration * a_this, + const guchar * a_prop) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + g_return_val_if_fail (a_prop, NULL); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->property + && cur->property->stryng + && cur->property->stryng->str) { + if (!strcmp (cur->property->stryng->str, + (const char *) a_prop)) { + return cur; + } + } + } + return NULL; +} + +/** + * cr_declaration_ref: + *@a_this: the current instance of #CRDeclaration. + * + *Increases the ref count of the current instance of #CRDeclaration. + */ +void +cr_declaration_ref (CRDeclaration * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + * cr_declaration_unref: + *@a_this: the current instance of #CRDeclaration. + * + *Decrements the ref count of the current instance of #CRDeclaration. + *If the ref count reaches zero, the current instance of #CRDeclaration + *if destroyed. + *Returns TRUE if @a_this was destroyed (ref count reached zero), + *FALSE otherwise. + */ +gboolean +cr_declaration_unref (CRDeclaration * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_declaration_destroy (a_this); + return TRUE; + } + return FALSE; +} + +/** + * cr_declaration_destroy: + *@a_this: the current instance of #CRDeclaration. + * + *Destructor of the declaration list. + */ +void +cr_declaration_destroy (CRDeclaration * a_this) +{ + CRDeclaration *cur = NULL; + + g_return_if_fail (a_this); + + /* + * Go to the last element of the list. + */ + for (cur = a_this; cur->next; cur = cur->next) + g_assert (cur->next->prev == cur); + + /* + * Walk backward the list and free each "next" element. + * Meanwhile, free each property/value pair contained in the list. + */ + for (; cur; cur = cur->prev) { + g_free (cur->next); + cur->next = NULL; + + if (cur->property) { + cr_string_destroy (cur->property); + cur->property = NULL; + } + + if (cur->value) { + cr_term_destroy (cur->value); + cur->value = NULL; + } + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-declaration.h b/src/3rdparty/libcroco/src/cr-declaration.h new file mode 100644 index 0000000..eee8be3 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-declaration.h @@ -0,0 +1,136 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_DECLARATION_H__ +#define __CR_DECLARATION_H__ + +#include <stdio.h> +#include "cr-utils.h" +#include "cr-term.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRDeclaration class. + */ + +/*forward declaration of what is defined in cr-statement.h*/ +typedef struct _CRStatement CRStatement ; + +/** + *The abstraction of a css declaration defined by the + *css2 spec in chapter 4. + *It is actually a chained list of property/value pairs. + */ +typedef struct _CRDeclaration CRDeclaration ; +struct _CRDeclaration +{ + /**The property.*/ + CRString *property ; + + /**The value of the property.*/ + CRTerm *value ; + + /*the ruleset that contains this declaration*/ + CRStatement *parent_statement ; + + /*the next declaration*/ + CRDeclaration *next ; + + /*the previous one declaration*/ + CRDeclaration *prev ; + + /*does the declaration have the important keyword ?*/ + gboolean important ; + + glong ref_count ; + + CRParsingLocation location ; + /*reserved for future usage*/ + gpointer rfu0 ; + gpointer rfu1 ; + gpointer rfu2 ; + gpointer rfu3 ; +} ; + + +CRDeclaration * cr_declaration_new (CRStatement *a_statement, + CRString *a_property, + CRTerm *a_value) ; + + +CRDeclaration * cr_declaration_parse_from_buf (CRStatement *a_statement, + const guchar *a_str, + enum CREncoding a_enc) ; + +CRDeclaration * cr_declaration_parse_list_from_buf (const guchar *a_str, + enum CREncoding a_enc) ; + +CRDeclaration * cr_declaration_append (CRDeclaration *a_this, + CRDeclaration *a_new) ; + +CRDeclaration * cr_declaration_append2 (CRDeclaration *a_this, + CRString *a_prop, + CRTerm *a_value) ; + +CRDeclaration * cr_declaration_prepend (CRDeclaration *a_this, + CRDeclaration *a_new) ; + +CRDeclaration * cr_declaration_unlink (CRDeclaration * a_decl) ; + +void +cr_declaration_dump (CRDeclaration const *a_this, + FILE *a_fp, glong a_indent, + gboolean a_one_per_line) ; + +void cr_declaration_dump_one (CRDeclaration const *a_this, + FILE *a_fp, glong a_indent) ; + +gint cr_declaration_nr_props (CRDeclaration const *a_this) ; + +CRDeclaration * cr_declaration_get_from_list (CRDeclaration *a_this, + int itemnr) ; + +CRDeclaration * cr_declaration_get_by_prop_name (CRDeclaration *a_this, + const guchar *a_str) ; + +gchar * cr_declaration_to_string (CRDeclaration const *a_this, + gulong a_indent) ; + +guchar * cr_declaration_list_to_string (CRDeclaration const *a_this, + gulong a_indent) ; + +guchar * cr_declaration_list_to_string2 (CRDeclaration const *a_this, + gulong a_indent, + gboolean a_one_decl_per_line) ; + +void cr_declaration_ref (CRDeclaration *a_this) ; + +gboolean cr_declaration_unref (CRDeclaration *a_this) ; + +void cr_declaration_destroy (CRDeclaration *a_this) ; + +G_END_DECLS + +#endif /*__CR_DECLARATION_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-doc-handler.c b/src/3rdparty/libcroco/src/cr-doc-handler.c new file mode 100644 index 0000000..b0ef13c --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-doc-handler.c @@ -0,0 +1,276 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPRYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-doc-handler.h" +#include "cr-parser.h" + +/** + *@CRDocHandler: + * + *The definition of the CRDocHandler class. + *Contains methods to instantiate, destroy, + *and initialize instances of #CRDocHandler + *to custom values. + */ + +#define PRIVATE(obj) (obj)->priv + +struct _CRDocHandlerPriv { + /** + *This pointer is to hold an application parsing context. + *For example, it used by the Object Model parser to + *store it parsing context. #CRParser does not touch it, but + *#CROMParser does. #CROMParser allocates this pointer at + *the beginning of the css document, and frees it at the end + *of the document. + */ + gpointer context; + + /** + *The place where #CROMParser puts the result of its parsing, if + *any. + */ + gpointer result; + /** + *a pointer to the parser used to parse + *the current document. + */ + CRParser *parser ; +}; + +/** + * cr_doc_handler_new: + *Constructor of #CRDocHandler. + * + *Returns the newly built instance of + *#CRDocHandler + * + */ +CRDocHandler * +cr_doc_handler_new (void) +{ + CRDocHandler *result = NULL; + + result = g_try_malloc (sizeof (CRDocHandler)); + + g_return_val_if_fail (result, NULL); + + memset (result, 0, sizeof (CRDocHandler)); + result->ref_count++; + + result->priv = g_try_malloc (sizeof (CRDocHandlerPriv)); + if (!result->priv) { + cr_utils_trace_info ("Out of memory exception"); + g_free (result); + return NULL; + } + + cr_doc_handler_set_default_sac_handler (result); + + return result; +} + +/** + * cr_doc_handler_get_ctxt: + *@a_this: the current instance of #CRDocHandler. + *@a_ctxt: out parameter. The new parsing context. + * + *Gets the private parsing context associated to the document handler + *The private parsing context is used by libcroco only. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_get_ctxt (CRDocHandler const * a_this, gpointer * a_ctxt) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + + *a_ctxt = a_this->priv->context; + + return CR_OK; +} + +/** + * cr_doc_handler_set_ctxt: + *@a_this: the current instance of #CRDocHandler + *@a_ctxt: a pointer to the parsing context. + * + *Sets the private parsing context. + *This is used by libcroco only. + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_ctxt (CRDocHandler * a_this, gpointer a_ctxt) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + a_this->priv->context = a_ctxt; + return CR_OK; +} + +/** + * cr_doc_handler_get_result: + *@a_this: the current instance of #CRDocHandler + *@a_result: out parameter. The returned result. + * + *Gets the private parsing result. + *The private parsing result is used by libcroco only. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_get_result (CRDocHandler const * a_this, gpointer * a_result) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + + *a_result = a_this->priv->result; + + return CR_OK; +} + +/** + * cr_doc_handler_set_result: + *@a_this: the current instance of #CRDocHandler + *@a_result: the new result. + * + *Sets the private parsing context. + *This is used by libcroco only. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_result (CRDocHandler * a_this, gpointer a_result) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + a_this->priv->result = a_result; + return CR_OK; +} + +/** + *cr_doc_handler_set_default_sac_handler: + *@a_this: a pointer to the current instance of #CRDocHandler. + * + *Sets the sac handlers contained in the current + *instance of DocHandler to the default handlers. + *For the time being the default handlers are + *test handlers. This is expected to change in a + *near future, when the libcroco gets a bit debugged. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_default_sac_handler (CRDocHandler * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->start_document = NULL; + a_this->end_document = NULL; + a_this->import_style = NULL; + a_this->namespace_declaration = NULL; + a_this->comment = NULL; + a_this->start_selector = NULL; + a_this->end_selector = NULL; + a_this->property = NULL; + a_this->start_font_face = NULL; + a_this->end_font_face = NULL; + a_this->start_media = NULL; + a_this->end_media = NULL; + a_this->start_page = NULL; + a_this->end_page = NULL; + a_this->ignorable_at_rule = NULL; + a_this->error = NULL; + a_this->unrecoverable_error = NULL; + return CR_OK; +} + +/** + * cr_doc_handler_ref: + *@a_this: the current instance of #CRDocHandler. + */ +void +cr_doc_handler_ref (CRDocHandler * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + * cr_doc_handler_unref: + *@a_this: the current instance of #CRDocHandler. + * + *Decreases the ref count of the current instance of #CRDocHandler. + *If the ref count reaches '0' then, destroys the instance. + * + *Returns TRUE if the instance as been destroyed, FALSE otherwise. + */ +gboolean +cr_doc_handler_unref (CRDocHandler * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count > 0) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_doc_handler_destroy (a_this); + return TRUE; + } + return FALSE ; +} + +/** + * cr_doc_handler_destroy: + *@a_this: the instance of #CRDocHandler to + *destroy. + * + *The destructor of the #CRDocHandler class. + */ +void +cr_doc_handler_destroy (CRDocHandler * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->priv) { + g_free (a_this->priv); + a_this->priv = NULL; + } + g_free (a_this); +} + +/** + * cr_doc_handler_associate_a_parser: + *Associates a parser to the current document handler + * + *@a_this: the current instance of document handler. + *@a_parser: the parser to associate. + */ +void +cr_doc_handler_associate_a_parser (CRDocHandler *a_this, + gpointer a_parser) +{ + g_return_if_fail (a_this && PRIVATE (a_this) + && a_parser) ; + + PRIVATE (a_this)->parser = a_parser ; +} diff --git a/src/3rdparty/libcroco/src/cr-doc-handler.h b/src/3rdparty/libcroco/src/cr-doc-handler.h new file mode 100644 index 0000000..d12673f --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-doc-handler.h @@ -0,0 +1,298 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_DOC_HANDLER_H__ +#define __CR_DOC_HANDLER_H__ + +/** + *@file + *The declaration of the #CRDocumentHandler class. + *This class is actually the parsing events handler. + */ + +#include <glib.h> +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-stylesheet.h" + +G_BEGIN_DECLS + + +typedef struct _CRDocHandler CRDocHandler ; + +struct _CRDocHandlerPriv ; +typedef struct _CRDocHandlerPriv CRDocHandlerPriv ; + + +/** + *The SAC document handler. + *An instance of this class is to + *be passed to a parser. Then, during the parsing + *the parser calls the convenient function pointer + *whenever a particular event (a css construction) occurs. + */ +struct _CRDocHandler +{ + CRDocHandlerPriv *priv ; + + /** + *This pointer is to be used by the application for + *it custom needs. It is there to extend the doc handler. + */ + gpointer app_data ; + + /** + *Is called at the beginning of the parsing of the document. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*start_document) (CRDocHandler *a_this) ; + + /** + *Is called to notify the end of the parsing of the document. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*end_document) (CRDocHandler *a_this) ; + + /** + *Is called to notify an at charset rule. + *@param a_this the document handler. + *@param a_charset the declared charset. + */ + void (*charset) (CRDocHandler *a_this, + CRString *a_charset, + CRParsingLocation *a_charset_sym_location) ; + + /** + *Is called to notify an import statement in + *the stylesheet. + *@param a_this the current instance of #CRDocHandler. + *@param a_media_list a doubly linked list of GString objects. + *Each GString object contains a string which is the + *destination media for style information. + *@param a_uri the uri of the imported style sheet. + *@param a_uri_default_ns the default namespace of URI + *@param a_location the parsing location of the '\@import' + *keyword. + *of the imported style sheet. + */ + void (*import_style) (CRDocHandler *a_this, + GList *a_media_list, + CRString *a_uri, + CRString *a_uri_default_ns, + CRParsingLocation *a_location) ; + + void (*import_style_result) (CRDocHandler *a_this, + GList *a_media_list, + CRString *a_uri, + CRString *a_uri_default_ns, + CRStyleSheet *a_sheet) ; + + /** + *Is called to notify a namespace declaration. + *Not used yet. + *@param a_this the current instance of #CRDocHandler. + *@param a_prefix the prefix of the namespace. + *@param a_uri the uri of the namespace. + *@param a_location the location of the "@namespace" keyword. + */ + void (*namespace_declaration) (CRDocHandler *a_this, + CRString *a_prefix, + CRString *a_uri, + CRParsingLocation *a_location) ; + + /** + *Is called to notify a comment. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_comment the comment. + */ + void (*comment) (CRDocHandler *a_this, + CRString *a_comment) ; + + /** + *Is called to notify the beginning of a rule + *statement. + *@param a_this the current instance of #CRDocHandler. + *@param a_selector_list the list of selectors that precedes + *the rule declarations. + */ + void (*start_selector) (CRDocHandler * a_this, + CRSelector *a_selector_list) ; + + /** + *Is called to notify the end of a rule statement. + *@param a_this the current instance of #CRDocHandler. + *@param a_selector_list the list of selectors that precedes + *the rule declarations. This pointer is the same as + *the one passed to start_selector() ; + */ + void (*end_selector) (CRDocHandler *a_this, + CRSelector *a_selector_list) ; + + + /** + *Is called to notify a declaration. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_name the name of the parsed property. + *@param a_expression a css expression that represents + *the value of the property. A css expression is + *actually a linked list of 'terms'. Each term can + *be linked to other using operators. + * + */ + void (*property) (CRDocHandler *a_this, + CRString *a_name, + CRTerm *a_expression, + gboolean a_is_important) ; + /** + *Is called to notify the start of a font face statement. + *The parser invokes this method at the beginning of every + *font face statement in the style sheet. There will + *be a corresponding end_font_face () event for every + *start_font_face () event. + * + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_location the parsing location of the "\@font-face" + *keyword. + */ + void (*start_font_face) (CRDocHandler *a_this, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a font face statement. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*end_font_face) (CRDocHandler *a_this) ; + + + /** + *Is called to notify the beginning of a media statement. + *The parser will invoke this method at the beginning of + *every media statement in the style sheet. There will be + *a corresponding end_media() event for every start_media() + *event. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_media_list a double linked list of + #CRString * objects. + *Each CRString objects is actually a destination media for + *the style information. + */ + void (*start_media) (CRDocHandler *a_this, + GList *a_media_list, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a media statement. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_media_list a double linked list of GString * objects. + *Each GString objects is actually a destination media for + *the style information. + */ + void (*end_media) (CRDocHandler *a_this, + GList *a_media_list) ; + + /** + *Is called to notify the beginning of a page statement. + *The parser invokes this function at the beginning of + *every page statement in the style sheet. There will be + *a corresponding end_page() event for every single + *start_page() event. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_name the name of the page (if any, null otherwise). + *@param a_pseudo_page the pseudo page (if any, null otherwise). + *@param a_location the parsing location of the "\@page" keyword. + */ + void (*start_page) (CRDocHandler *a_this, + CRString *a_name, + CRString *a_pseudo_page, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a page statement. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_name the name of the page (if any, null otherwise). + *@param a_pseudo_page the pseudo page (if any, null otherwise). + */ + void (*end_page) (CRDocHandler *a_this, + CRString *a_name, + CRString *pseudo_page) ; + + /** + *Is Called to notify an unknown at-rule not supported + *by this parser. + */ + void (*ignorable_at_rule) (CRDocHandler *a_this, + CRString *a_name) ; + + /** + *Is called to notify a parsing error. After this error + *the application must ignore the rule being parsed, if + *any. After completion of this callback, + *the parser will then try to resume the parsing, + *ignoring the current error. + */ + void (*error) (CRDocHandler *a_this) ; + + /** + *Is called to notify an unrecoverable parsing error. + *This is the place to put emergency routines that free allocated + *resources. + */ + void (*unrecoverable_error) (CRDocHandler *a_this) ; + + gboolean resolve_import ; + gulong ref_count ; +} ; + +CRDocHandler * cr_doc_handler_new (void) ; + +enum CRStatus cr_doc_handler_set_result (CRDocHandler *a_this, gpointer a_result) ; + +enum CRStatus cr_doc_handler_get_result (CRDocHandler const *a_this, gpointer * a_result) ; + +enum CRStatus cr_doc_handler_set_ctxt (CRDocHandler *a_this, gpointer a_ctxt) ; + +enum CRStatus cr_doc_handler_get_ctxt (CRDocHandler const *a_this, gpointer * a_ctxt) ; + +enum CRStatus cr_doc_handler_set_default_sac_handler (CRDocHandler *a_this) ; + +void cr_doc_handler_associate_a_parser (CRDocHandler *a_this, + gpointer a_parser) ; + +void cr_doc_handler_ref (CRDocHandler *a_this) ; + +gboolean cr_doc_handler_unref (CRDocHandler *a_this) ; + +void cr_doc_handler_destroy (CRDocHandler *a_this) ; + +G_END_DECLS + +#endif /*__CR_DOC_HANDLER_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-enc-handler.c b/src/3rdparty/libcroco/src/cr-enc-handler.c new file mode 100644 index 0000000..65adc7a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-enc-handler.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +/** + *@file + *The definition of the #CREncHandler class. + */ + +#include "cr-enc-handler.h" +#include "cr-utils.h" + +#include <string.h> + +struct CREncAlias { + const gchar *name; + enum CREncoding encoding; +}; + +static struct CREncAlias gv_default_aliases[] = { + {"UTF-8", CR_UTF_8}, + {"UTF_8", CR_UTF_8}, + {"UTF8", CR_UTF_8}, + {"UTF-16", CR_UTF_16}, + {"UTF_16", CR_UTF_16}, + {"UTF16", CR_UTF_16}, + {"UCS1", CR_UCS_1}, + {"UCS-1", CR_UCS_1}, + {"UCS_1", CR_UCS_1}, + {"ISO-8859-1", CR_UCS_1}, + {"ISO_8859-1", CR_UCS_1}, + {"UCS-1", CR_UCS_1}, + {"UCS_1", CR_UCS_1}, + {"UCS4", CR_UCS_4}, + {"UCS-4", CR_UCS_4}, + {"UCS_4", CR_UCS_4}, + {"ASCII", CR_ASCII}, + {0, 0} +}; + +static CREncHandler gv_default_enc_handlers[] = { + {CR_UCS_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {CR_ISO_8859_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {CR_ASCII, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {0, NULL, NULL, NULL, NULL} +}; + +/** + * cr_enc_handler_get_instance: + *@a_enc: the encoding of the Handler. + * + *Gets the instance of encoding handler. + *This function implements a singleton pattern. + * + *Returns the instance of #CREncHandler. + */ +CREncHandler * +cr_enc_handler_get_instance (enum CREncoding a_enc) +{ + gulong i = 0; + + for (i = 0; gv_default_enc_handlers[i].encoding; i++) { + if (gv_default_enc_handlers[i].encoding == a_enc) { + return (CREncHandler *) & gv_default_enc_handlers[i]; + } + } + + return NULL; +} + +/** + * cr_enc_handler_resolve_enc_alias: + *@a_alias_name: the encoding name. + *@a_enc: output param. The returned encoding type + *or 0 if the alias is not supported. + * + *Given an encoding name (called an alias name) + *the function returns the matching encoding type. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_enc_handler_resolve_enc_alias (const guchar * a_alias_name, + enum CREncoding *a_enc) +{ + gulong i = 0; + guchar *alias_name_up = NULL; + enum CRStatus status = CR_ENCODING_NOT_FOUND_ERROR; + + g_return_val_if_fail (a_alias_name != NULL, CR_BAD_PARAM_ERROR); + + alias_name_up = (guchar *) g_ascii_strup ((const gchar *) a_alias_name, -1); + + for (i = 0; gv_default_aliases[i].name; i++) { + if (!strcmp (gv_default_aliases[i].name, (const gchar *) alias_name_up)) { + *a_enc = gv_default_aliases[i].encoding; + status = CR_OK; + break; + } + } + + return status; +} + +/** + * cr_enc_handler_convert_input: + *@a_this: the current instance of #CREncHandler. + *@a_in: the input buffer to convert. + *@a_in_len: in/out parameter. The len of the input + *buffer to convert. After return, contains the number of + *bytes actually consumed. + *@a_out: output parameter. The converted output buffer. + *Must be freed by the buffer. + *@a_out_len: output parameter. The length of the output buffer. + * + *Converts a raw input buffer into an utf8 buffer. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_enc_handler_convert_input (CREncHandler * a_this, + const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_in && a_in_len && a_out, + CR_BAD_PARAM_ERROR); + + if (a_this->decode_input == NULL) + return CR_OK; + + if (a_this->enc_str_len_as_utf8) { + status = a_this->enc_str_len_as_utf8 (a_in, + &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + } else { + *a_out_len = *a_in_len; + } + + *a_out = g_malloc0 (*a_out_len); + + status = a_this->decode_input (a_in, a_in_len, *a_out, a_out_len); + + if (status != CR_OK) { + g_free (*a_out); + *a_out = NULL; + } + + g_return_val_if_fail (status == CR_OK, status); + + return CR_OK; +} diff --git a/src/3rdparty/libcroco/src/cr-enc-handler.h b/src/3rdparty/libcroco/src/cr-enc-handler.h new file mode 100644 index 0000000..0727764 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-enc-handler.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +/** + *@file: + *The declaration of the #CREncHandler class. + * + */ + +#ifndef __CR_ENC_HANDLER_H__ +#define __CR_ENC_HANDLER_H__ + +#include "cr-utils.h" + +G_BEGIN_DECLS + + +typedef struct _CREncHandler CREncHandler ; + +typedef enum CRStatus (*CREncInputFunc) (const guchar * a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) ; + +typedef enum CRStatus (*CREncOutputFunc) (const guchar * a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) ; + +typedef enum CRStatus (*CREncInputStrLenAsUtf8Func) +(const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_in_size); + +typedef enum CRStatus (*CREncUtf8StrLenAsOutputFunc) +(const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_in_size) ; + +/** + *This class is responsible of the + *the encoding conversions stuffs in + *libcroco. + */ + +struct _CREncHandler +{ + enum CREncoding encoding ; + CREncInputFunc decode_input ; + CREncInputFunc encode_output ; + CREncInputStrLenAsUtf8Func enc_str_len_as_utf8 ; + CREncUtf8StrLenAsOutputFunc utf8_str_len_as_enc ; +} ; + +CREncHandler * +cr_enc_handler_get_instance (enum CREncoding a_enc) ; + +enum CRStatus +cr_enc_handler_resolve_enc_alias (const guchar *a_alias_name, + enum CREncoding *a_enc) ; + +enum CRStatus +cr_enc_handler_convert_input (CREncHandler *a_this, + const guchar *a_in, + gulong *a_in_len, + guchar **a_out, + gulong *a_out_len) ; + +G_END_DECLS + +#endif /*__CR_ENC_HANDLER_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-fonts.c b/src/3rdparty/libcroco/src/cr-fonts.c new file mode 100644 index 0000000..3f7a287 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-fonts.c @@ -0,0 +1,943 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + *See COPYRIGHTS file for copyright information + */ + +#include "cr-fonts.h" +#include <string.h> + +static enum CRStatus +cr_font_family_to_string_real (CRFontFamily const * a_this, + gboolean a_walk_list, GString ** a_string) +{ + guchar const *name = NULL; + enum CRStatus result = CR_OK; + + if (!*a_string) { + *a_string = g_string_new (NULL); + g_return_val_if_fail (*a_string, + CR_INSTANCIATION_FAILED_ERROR); + } + + if (!a_this) { + g_string_append (*a_string, "NULL"); + return CR_OK; + } + + switch (a_this->type) { + case FONT_FAMILY_SANS_SERIF: + name = (guchar const *) "sans-serif"; + break; + + case FONT_FAMILY_SERIF: + name = (guchar const *) "sans-serif"; + break; + + case FONT_FAMILY_CURSIVE: + name = (guchar const *) "cursive"; + break; + + case FONT_FAMILY_FANTASY: + name = (guchar const *) "fantasy"; + break; + + case FONT_FAMILY_MONOSPACE: + name = (guchar const *) "monospace"; + break; + + case FONT_FAMILY_NON_GENERIC: + name = (guchar const *) a_this->name; + break; + + default: + name = NULL; + break; + } + + if (name) { + if (a_this->prev) { + g_string_append_printf (*a_string, ", %s", name); + } else { + g_string_append (*a_string, (const gchar *) name); + } + } + if (a_walk_list == TRUE && a_this->next) { + result = cr_font_family_to_string_real (a_this->next, + TRUE, a_string); + } + return result; +} + +static const gchar * +cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize + a_code) +{ + gchar const *str = NULL; + + switch (a_code) { + case FONT_SIZE_XX_SMALL: + str = "xx-small"; + break; + case FONT_SIZE_X_SMALL: + str = "x-small"; + break; + case FONT_SIZE_SMALL: + str = "small"; + break; + case FONT_SIZE_MEDIUM: + str = "medium"; + break; + case FONT_SIZE_LARGE: + str = "large"; + break; + case FONT_SIZE_X_LARGE: + str = "x-large"; + break; + case FONT_SIZE_XX_LARGE: + str = "xx-large"; + break; + default: + str = "unknown absolute font size value"; + } + return str; +} + +static const gchar * +cr_relative_font_size_to_string (enum CRRelativeFontSize a_code) +{ + gchar const *str = NULL; + + switch (a_code) { + case FONT_SIZE_LARGER: + str = "larger"; + break; + case FONT_SIZE_SMALLER: + str = "smaller"; + break; + default: + str = "unknown relative font size value"; + break; + } + return str; +} + +/** + * cr_font_family_new: + * @a_type: the type of font family to create. + * @a_name: the name of the font family. + * + * create a font family. + * + * Returns the newly built font family. + */ +CRFontFamily * +cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name) +{ + CRFontFamily *result = NULL; + + result = g_try_malloc (sizeof (CRFontFamily)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRFontFamily)); + result->type = a_type; + + cr_font_family_set_name (result, a_name); + + return result; +} + +/** + * cr_font_family_to_string: + * @a_this: the current instance of #CRFontFamily. + * @a_walk_font_family_list: whether the serialize the entire list. + * + * Returns the seriliazed font family. The caller has to free it using + * g_free(). + */ +guchar * +cr_font_family_to_string (CRFontFamily const * a_this, + gboolean a_walk_font_family_list) +{ + enum CRStatus status = CR_OK; + guchar *result = NULL; + GString *stringue = NULL; + + if (!a_this) { + result = (guchar *) g_strdup ("NULL"); + g_return_val_if_fail (result, NULL); + return result; + } + status = cr_font_family_to_string_real (a_this, + a_walk_font_family_list, + &stringue); + + if (status == CR_OK && stringue) { + result = (guchar *) stringue->str; + g_string_free (stringue, FALSE); + stringue = NULL; + + } else { + if (stringue) { + g_string_free (stringue, TRUE); + stringue = NULL; + } + } + + return result; +} + +/** + * cr_font_family_set_name: + * @a_this: the current instance of #CRFontFamily. + * @a_name: the new name + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + /* + *only non generic font families can have a name + */ + + if (a_this->type != FONT_FAMILY_NON_GENERIC) { + return CR_BAD_PARAM_ERROR; + } + + if (a_this->name) { + g_free (a_this->name); + a_this->name = NULL; + } + + a_this->name = a_name; + return CR_OK; +} + +/** + * cr_font_family_append: + * @a_this: the current instance of #CRFontFamily. + * @a_family_to_append: the font family to append to the list + * + * Returns the new font family list. + */ +CRFontFamily * +cr_font_family_append (CRFontFamily * a_this, + CRFontFamily * a_family_to_append) +{ + CRFontFamily *cur_ff = NULL; + + g_return_val_if_fail (a_family_to_append, NULL); + + if (!a_this) + return a_family_to_append; + + for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ; + + cur_ff->next = a_family_to_append; + a_family_to_append->prev = cur_ff; + + return a_this; + +} + +/** + * cr_font_family_prepend: + * @a_this: the current instance #CRFontFamily. + * @a_family_to_prepend: the font family to prepend to the list. + * + * Returns the font family list. + */ +CRFontFamily * +cr_font_family_prepend (CRFontFamily * a_this, + CRFontFamily * a_family_to_prepend) +{ + g_return_val_if_fail (a_this && a_family_to_prepend, NULL); + + if (!a_this) + return a_family_to_prepend; + + a_family_to_prepend->next = a_this; + a_this->prev = a_family_to_prepend; + + return a_family_to_prepend; +} + +/** + * cr_font_family_destroy: + * @a_this: the current instance of #CRFontFamily. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_family_destroy (CRFontFamily * a_this) +{ + CRFontFamily *cur_ff = NULL; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ; + + for (; cur_ff; cur_ff = cur_ff->prev) { + if (a_this->name) { + g_free (a_this->name); + a_this->name = NULL; + } + + if (cur_ff->next) { + g_free (cur_ff->next); + + } + + if (cur_ff->prev == NULL) { + g_free (a_this); + } + } + + return CR_OK; +} + +/*************************************************** + *'font-size' manipulation functions definitions + ***************************************************/ + +/** + * cr_font_size_new: + * + * Returns the newly created font size. + */ +CRFontSize * +cr_font_size_new (void) +{ + CRFontSize *result = NULL; + + result = g_try_malloc (sizeof (CRFontSize)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRFontSize)); + + return result; +} + +/** + * cr_font_size_clear: + * @a_this: the current instance of #CRFontSize + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_clear (CRFontSize * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + switch (a_this->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + case RELATIVE_FONT_SIZE: + case INHERITED_FONT_SIZE: + memset (a_this, 0, sizeof (CRFontSize)); + break; + + case ABSOLUTE_FONT_SIZE: + memset (a_this, 0, sizeof (CRFontSize)); + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + } + + return CR_OK; +} + +/** + * cr_font_size_copy: + * @a_dst: the destination #CRFontSize (where to copy to). + * @a_src: the source #CRFontSize (where to copy from). + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_copy (CRFontSize * a_dst, CRFontSize const * a_src) +{ + g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR); + + switch (a_src->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + case RELATIVE_FONT_SIZE: + case INHERITED_FONT_SIZE: + cr_font_size_clear (a_dst); + memcpy (a_dst, a_src, sizeof (CRFontSize)); + break; + + case ABSOLUTE_FONT_SIZE: + cr_font_size_clear (a_dst); + cr_num_copy (&a_dst->value.absolute, + &a_src->value.absolute); + a_dst->type = a_src->type; + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + } + return CR_OK; +} + +/** + * cr_font_size_set_predefined_absolute_font_size: + * @a_this: the current instance of #CRFontSize. + * @a_predefined: what to set. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, + enum CRPredefinedAbsoluteFontSize a_predefined) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_predefined < NB_PREDEFINED_ABSOLUTE_FONT_SIZES, + CR_BAD_PARAM_ERROR) ; + + a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_this->value.predefined = a_predefined ; + + return CR_OK ; +} + +/** + * cr_font_size_set_relative_font_size: + * @a_this: the current instance of #CRFontSize + * @a_relative: the new relative font size + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_set_relative_font_size (CRFontSize *a_this, + enum CRRelativeFontSize a_relative) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_relative < NB_RELATIVE_FONT_SIZE, + CR_BAD_PARAM_ERROR) ; + + a_this->type = RELATIVE_FONT_SIZE ; + a_this->value.relative = a_relative ; + return CR_OK ; +} + +/** + * cr_font_size_set_absolute_font_size: + * @a_this: the current instance of #CRFontSize + * @a_num_type: the type of number to set. + * @a_value: the actual value to set. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_set_absolute_font_size (CRFontSize *a_this, + enum CRNumType a_num_type, + gdouble a_value) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_num_type < NB_NUM_TYPE, + CR_BAD_PARAM_ERROR) ; + + a_this->type = ABSOLUTE_FONT_SIZE ; + cr_num_set (&a_this->value.absolute, + a_value, a_num_type) ; + return CR_OK ; +} + +/** + * cr_font_size_set_to_inherit: + * @a_this: the current instance of #CRFontSize + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_font_size_set_to_inherit (CRFontSize *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + cr_font_size_clear (a_this) ; + a_this->type = INHERITED_FONT_SIZE ; + + return CR_OK ; +} + +/** + * cr_font_size_is_set_to_inherit: + * @a_this: the current instance of #CRFontSize. + * + * Returns TRUE if the current instance is set to 'inherit'. + */ +gboolean +cr_font_size_is_set_to_inherit (CRFontSize const *a_this) +{ + g_return_val_if_fail (a_this, FALSE) ; + + return a_this->type == INHERITED_FONT_SIZE ; +} + +/** + * cr_font_size_to_string: + * @a_this: the current instance of #CRFontSize + * + * Returns the serialized form of #CRFontSize. The returned string + * has to bee freed using g_free(). + */ +gchar * +cr_font_size_to_string (CRFontSize const * a_this) +{ + gchar *str = NULL; + + if (!a_this) { + str = g_strdup ("NULL"); + g_return_val_if_fail (str, NULL); + return str; + } + switch (a_this->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + str = g_strdup (cr_predefined_absolute_font_size_to_string + (a_this->value.predefined)); + break; + case ABSOLUTE_FONT_SIZE: + str = (gchar *) cr_num_to_string (&a_this->value.absolute); + break; + case RELATIVE_FONT_SIZE: + str = g_strdup (cr_relative_font_size_to_string + (a_this->value.relative)); + break; + case INHERITED_FONT_SIZE: + str = g_strdup ("inherit"); + break; + default: + break; + } + return str; +} + +/** + * cr_font_size_get_smaller_predefined: + * @a_font_size: the font size to consider. + * @a_smaller_size: out parameter. The a smaller value than @a_font_size. + */ +void +cr_font_size_get_smaller_predefined_font_size + (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_smaller_size) +{ + enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ; + + g_return_if_fail (a_smaller_size) ; + g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ; + + switch (a_font_size) { + case FONT_SIZE_XX_SMALL: + result = FONT_SIZE_XX_SMALL ; + break ; + case FONT_SIZE_X_SMALL: + result = FONT_SIZE_XX_SMALL ; + break ; + case FONT_SIZE_SMALL: + result = FONT_SIZE_X_SMALL; + break ; + case FONT_SIZE_MEDIUM: + result = FONT_SIZE_SMALL; + break ; + case FONT_SIZE_LARGE: + result = FONT_SIZE_MEDIUM; + break ; + case FONT_SIZE_X_LARGE: + result = FONT_SIZE_LARGE; + break ; + case FONT_SIZE_XX_LARGE: + result = FONT_SIZE_XX_LARGE; + break ; + case FONT_SIZE_INHERIT: + cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ; + result = FONT_SIZE_MEDIUM ; + break ; + default: + cr_utils_trace_info ("Unknown FONT_SIZE") ; + result = FONT_SIZE_MEDIUM ; + break ; + } + *a_smaller_size = result ; +} + + +/** + * cr_font_size_get_larger_predefined_font_size: + * @a_font_size: the font size to consider. + * @a_larger_size: out parameter. the font size considered larger than + * @a_font_size. + * + */ +void +cr_font_size_get_larger_predefined_font_size + (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_larger_size) +{ + enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ; + + g_return_if_fail (a_larger_size) ; + g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ; + + switch (a_font_size) { + case FONT_SIZE_XX_SMALL: + result = FONT_SIZE_X_SMALL ; + break ; + case FONT_SIZE_X_SMALL: + result = FONT_SIZE_SMALL ; + break ; + case FONT_SIZE_SMALL: + result = FONT_SIZE_MEDIUM; + break ; + case FONT_SIZE_MEDIUM: + result = FONT_SIZE_LARGE; + break ; + case FONT_SIZE_LARGE: + result = FONT_SIZE_X_LARGE; + break ; + case FONT_SIZE_X_LARGE: + result = FONT_SIZE_XX_LARGE ; + break ; + case FONT_SIZE_XX_LARGE: + result = FONT_SIZE_XX_LARGE; + break ; + case FONT_SIZE_INHERIT: + cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ; + result = FONT_SIZE_MEDIUM ; + break ; + default: + cr_utils_trace_info ("Unknown FONT_SIZE") ; + result = FONT_SIZE_MEDIUM ; + break ; + } + *a_larger_size = result ; +} + +/** + * cr_font_size_is_predefined_absolute_font_size: + * @a_font_size: the font size to consider. + * + * Returns TRUE if the instance is an predefined absolute font size, FALSE + * otherwise. + */ +gboolean +cr_font_size_is_predefined_absolute_font_size + (enum CRPredefinedAbsoluteFontSize a_font_size) +{ + if ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) { + return TRUE ; + } else { + return FALSE ; + } +} + +/** + * cr_font_size_adjust_to_string: + * @a_this: the instance of #CRFontSizeAdjust. + * + * Returns the serialized form of #CRFontSizeAdjust + */ +gchar * +cr_font_size_adjust_to_string (CRFontSizeAdjust const * a_this) +{ + gchar *str = NULL; + + if (!a_this) { + str = g_strdup ("NULL"); + g_return_val_if_fail (str, NULL); + return str; + } + + switch (a_this->type) { + case FONT_SIZE_ADJUST_NONE: + str = g_strdup ("none"); + break; + case FONT_SIZE_ADJUST_NUMBER: + if (a_this->num) + str = (gchar *) cr_num_to_string (a_this->num); + else + str = g_strdup ("unknown font-size-adjust property value"); /* Should raise an error no?*/ + break; + case FONT_SIZE_ADJUST_INHERIT: + str = g_strdup ("inherit"); + } + return str; +} + +/** + * cr_font_style_to_string: + * @a_code: the current instance of #CRFontStyle . + * + * Returns the serialized #CRFontStyle. The caller must free the returned + * string using g_free(). + */ +const gchar * +cr_font_style_to_string (enum CRFontStyle a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_STYLE_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_STYLE_ITALIC: + str = (gchar *) "italic"; + break; + case FONT_STYLE_OBLIQUE: + str = (gchar *) "oblique"; + break; + case FONT_STYLE_INHERIT: + str = (gchar *) "inherit"; + break; + default: + str = (gchar *) "unknown font style value"; + break; + } + return str; +} + +/** + * cr_font_variant_to_string: + * @a_code: the current instance of #CRFontVariant. + * + * Returns the serialized form of #CRFontVariant. The caller has + * to free the returned string using g_free(). + */ +const gchar * +cr_font_variant_to_string (enum CRFontVariant a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_VARIANT_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_VARIANT_SMALL_CAPS: + str = (gchar *) "small-caps"; + break; + case FONT_VARIANT_INHERIT: + str = (gchar *) "inherit"; + break; + } + return str; +} + +/** + * cr_font_weight_get_bolder: + * @a_weight: the #CRFontWeight to consider. + * + * Returns a font weight bolder than @a_weight + */ +enum CRFontWeight +cr_font_weight_get_bolder (enum CRFontWeight a_weight) +{ + if (a_weight == FONT_WEIGHT_INHERIT) { + cr_utils_trace_info ("can't return a bolder weight for FONT_WEIGHT_INHERIT") ; + return a_weight; + } else if (a_weight >= FONT_WEIGHT_900) { + return FONT_WEIGHT_900 ; + } else if (a_weight < FONT_WEIGHT_NORMAL) { + return FONT_WEIGHT_NORMAL ; + } else if (a_weight == FONT_WEIGHT_BOLDER + || a_weight == FONT_WEIGHT_LIGHTER) { + cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ; + return FONT_WEIGHT_NORMAL ; + } else { + return a_weight << 1 ; + } +} + +/** + * cr_font_weight_to_string: + * @a_code: the font weight to consider. + * + * Returns the serialized form of #CRFontWeight. + */ +const gchar * +cr_font_weight_to_string (enum CRFontWeight a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_WEIGHT_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_WEIGHT_BOLD: + str = (gchar *) "bold"; + break; + case FONT_WEIGHT_BOLDER: + str = (gchar *) "bolder"; + break; + case FONT_WEIGHT_LIGHTER: + str = (gchar *) "lighter"; + break; + case FONT_WEIGHT_100: + str = (gchar *) "100"; + break; + case FONT_WEIGHT_200: + str = (gchar *) "200"; + break; + case FONT_WEIGHT_300: + str = (gchar *) "300"; + break; + case FONT_WEIGHT_400: + str = (gchar *) "400"; + break; + case FONT_WEIGHT_500: + str = (gchar *) "500"; + break; + case FONT_WEIGHT_600: + str = (gchar *) "600"; + break; + case FONT_WEIGHT_700: + str = (gchar *) "700"; + break; + case FONT_WEIGHT_800: + str = (gchar *) "800"; + break; + case FONT_WEIGHT_900: + str = (gchar *) "900"; + break; + case FONT_WEIGHT_INHERIT: + str = (gchar *) "inherit"; + break; + default: + str = (gchar *) "unknown font-weight property value"; + break; + } + return str; +} + +/** + * cr_font_stretch_to_string: + * @a_code: the instance of #CRFontStretch to consider. + * + * Returns the serialized form of #CRFontStretch. + */ +const gchar * +cr_font_stretch_to_string (enum CRFontStretch a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_STRETCH_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_STRETCH_WIDER: + str = (gchar *) "wider"; + break; + case FONT_STRETCH_NARROWER: + str = (gchar *) "narrower"; + break; + case FONT_STRETCH_ULTRA_CONDENSED: + str = (gchar *) "ultra-condensed"; + break; + case FONT_STRETCH_EXTRA_CONDENSED: + str = (gchar *) "extra-condensed"; + break; + case FONT_STRETCH_CONDENSED: + str = (gchar *) "condensed"; + break; + case FONT_STRETCH_SEMI_CONDENSED: + str = (gchar *) "semi-condensed"; + break; + case FONT_STRETCH_SEMI_EXPANDED: + str = (gchar *) "semi-expanded"; + break; + case FONT_STRETCH_EXPANDED: + str = (gchar *) "expanded"; + break; + case FONT_STRETCH_EXTRA_EXPANDED: + str = (gchar *) "extra-expaned"; + break; + case FONT_STRETCH_ULTRA_EXPANDED: + str = (gchar *) "ultra-expanded"; + break; + case FONT_STRETCH_INHERIT: + str = (gchar *) "inherit"; + break; + } + return str; +} + +/** + * cr_font_size_destroy: + * @a_font_size: the font size to destroy + * + */ +void +cr_font_size_destroy (CRFontSize * a_font_size) +{ + g_return_if_fail (a_font_size); + + g_free (a_font_size) ; +} + +/******************************************************* + *'font-size-adjust' manipulation function definition + *******************************************************/ + +/** + * cr_font_size_adjust_new: + * + * Returns a newly built instance of #CRFontSizeAdjust + */ +CRFontSizeAdjust * +cr_font_size_adjust_new (void) +{ + CRFontSizeAdjust *result = NULL; + + result = g_try_malloc (sizeof (CRFontSizeAdjust)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRFontSizeAdjust)); + + return result; +} + +/** + * cr_font_size_adjust_destroy: + * @a_this: the current instance of #CRFontSizeAdjust. + * + */ +void +cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) { + cr_num_destroy (a_this->num); + a_this->num = NULL; + } +} diff --git a/src/3rdparty/libcroco/src/cr-fonts.h b/src/3rdparty/libcroco/src/cr-fonts.h new file mode 100644 index 0000000..9eaeeeb --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-fonts.h @@ -0,0 +1,315 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_FONTS_H__ +#define __CR_FONTS_H__ + +#include "cr-utils.h" +#include "cr-num.h" + +/** + *@file + *Various type declarations about font selection related + *properties. + */ +G_BEGIN_DECLS + + +enum CRFontFamilyType +{ + FONT_FAMILY_SANS_SERIF, + FONT_FAMILY_SERIF, + FONT_FAMILY_CURSIVE, + FONT_FAMILY_FANTASY, + FONT_FAMILY_MONOSPACE, + FONT_FAMILY_NON_GENERIC, + FONT_FAMILY_INHERIT, + /**/ + NB_FONT_FAMILIE_TYPES +} ; + +typedef struct _CRFontFamily CRFontFamily ; + +struct _CRFontFamily +{ + enum CRFontFamilyType type ; + + /* + *The name of the font family, in case + *it is non generic. + *Is set only if the type is FONT_FAMILY_NON_GENERIC. + */ + guchar *name ; + + CRFontFamily *next ; + CRFontFamily *prev ; +} ; + + +/** + *The different types + *of absolute font size. + *This is used by the 'font-size' + *property defined in css2 spec + *in chapter 15.2.4 . + *These values a indexes of + *table of size so please, do not + *change their definition order unless + *you know what you are doing. + */ +enum CRPredefinedAbsoluteFontSize +{ + FONT_SIZE_XX_SMALL=0, + FONT_SIZE_X_SMALL, + FONT_SIZE_SMALL, + FONT_SIZE_MEDIUM, + FONT_SIZE_LARGE, + FONT_SIZE_X_LARGE, + FONT_SIZE_XX_LARGE, + FONT_SIZE_INHERIT, + NB_PREDEFINED_ABSOLUTE_FONT_SIZES +} ; + +/** + *The different types + *of relative font size. + *This is used by the 'font-size' + *property defined in css2 spec + *in chapter 15.2.4 . + *These values a indexes of + *table of size so please, do not + *change their definition order unless + *you know what you are doing. + */ +enum CRRelativeFontSize +{ + FONT_SIZE_LARGER, + FONT_SIZE_SMALLER, + NB_RELATIVE_FONT_SIZE +} ; + +/** + *The type of font-size property. + *Used to define the type of #CRFontSize . + *See css2 spec chapter 15.2.4 to understand. + */ +enum CRFontSizeType { + /** + *If the type of #CRFontSize is + *PREDEFINED_ABSOLUTE_FONT_SIZE, + *the CRFontSize::value.predefined_absolute + *field will be defined. + */ + PREDEFINED_ABSOLUTE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *ABSOLUTE_FONT_SIZE, + *the CRFontSize::value.absolute + *field will be defined. + */ + ABSOLUTE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *RELATIVE_FONT_SIZE, + *the CRFontSize::value.relative + *field will be defined. + */ + RELATIVE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *INHERITED_FONT_SIZE, + *the None of the field of the CRFontSize::value enum + *will be defined. + */ + INHERITED_FONT_SIZE, + + NB_FONT_SIZE_TYPE +} ; + +typedef struct _CRFontSize CRFontSize ; +struct _CRFontSize { + enum CRFontSizeType type ; + union { + enum CRPredefinedAbsoluteFontSize predefined ; + enum CRRelativeFontSize relative ; + CRNum absolute ; + } value; +} ; + +enum CRFontSizeAdjustType +{ + FONT_SIZE_ADJUST_NONE = 0, + FONT_SIZE_ADJUST_NUMBER, + FONT_SIZE_ADJUST_INHERIT +} ; +typedef struct _CRFontSizeAdjust CRFontSizeAdjust ; +struct _CRFontSizeAdjust +{ + enum CRFontSizeAdjustType type ; + CRNum *num ; +} ; + +enum CRFontStyle +{ + FONT_STYLE_NORMAL=0, + FONT_STYLE_ITALIC, + FONT_STYLE_OBLIQUE, + FONT_STYLE_INHERIT +} ; + +enum CRFontVariant +{ + FONT_VARIANT_NORMAL=0, + FONT_VARIANT_SMALL_CAPS, + FONT_VARIANT_INHERIT +} ; + +enum CRFontWeight +{ + FONT_WEIGHT_NORMAL = 1, + FONT_WEIGHT_BOLD = 1<<1, + FONT_WEIGHT_BOLDER = 1<<2, + FONT_WEIGHT_LIGHTER = 1<<3, + FONT_WEIGHT_100 = 1<<4, + FONT_WEIGHT_200 = 1<<5, + FONT_WEIGHT_300 = 1<<6, + FONT_WEIGHT_400 = 1<<7, + FONT_WEIGHT_500 = 1<<8, + FONT_WEIGHT_600 = 1<<9, + FONT_WEIGHT_700 = 1<<10, + FONT_WEIGHT_800 = 1<<11, + FONT_WEIGHT_900 = 1<<12, + FONT_WEIGHT_INHERIT = 1<<13, + NB_FONT_WEIGHTS +} ; + +enum CRFontStretch +{ + FONT_STRETCH_NORMAL=0, + FONT_STRETCH_WIDER, + FONT_STRETCH_NARROWER, + FONT_STRETCH_ULTRA_CONDENSED, + FONT_STRETCH_EXTRA_CONDENSED, + FONT_STRETCH_CONDENSED, + FONT_STRETCH_SEMI_CONDENSED, + FONT_STRETCH_SEMI_EXPANDED, + FONT_STRETCH_EXPANDED, + FONT_STRETCH_EXTRA_EXPANDED, + FONT_STRETCH_ULTRA_EXPANDED, + FONT_STRETCH_INHERIT +} ; + +/************************************** + *'font-family' manipulation functions + ***************************************/ +CRFontFamily * +cr_font_family_new (enum CRFontFamilyType a_type, guchar *a_name) ; + +CRFontFamily * +cr_font_family_append (CRFontFamily *a_this, + CRFontFamily *a_family_to_append) ; + +guchar * +cr_font_family_to_string (CRFontFamily const *a_this, + gboolean a_walk_font_family_list) ; + +CRFontFamily * +cr_font_family_prepend (CRFontFamily *a_this, + CRFontFamily *a_family_to_prepend); + +enum CRStatus +cr_font_family_destroy (CRFontFamily *a_this) ; + +enum CRStatus +cr_font_family_set_name (CRFontFamily *a_this, guchar *a_name) ; + + +/************************************ + *'font-size' manipulation functions + ***********************************/ + +CRFontSize * cr_font_size_new (void) ; + +enum CRStatus cr_font_size_clear (CRFontSize *a_this) ; + +enum CRStatus cr_font_size_copy (CRFontSize *a_dst, + CRFontSize const *a_src) ; +enum CRStatus cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, + enum CRPredefinedAbsoluteFontSize a_predefined) ; +enum CRStatus cr_font_size_set_relative_font_size (CRFontSize *a_this, + enum CRRelativeFontSize a_relative) ; + +enum CRStatus cr_font_size_set_absolute_font_size (CRFontSize *a_this, + enum CRNumType a_num_type, + gdouble a_value) ; + +enum CRStatus cr_font_size_set_to_inherit (CRFontSize *a_this) ; + +gboolean cr_font_size_is_set_to_inherit (CRFontSize const *a_this) ; + +gchar* cr_font_size_to_string (CRFontSize const *a_this) ; + +void cr_font_size_destroy (CRFontSize *a_font_size) ; + +/******************************************************* + *'font-size-adjust' manipulation function declarations + *******************************************************/ + +CRFontSizeAdjust * cr_font_size_adjust_new (void) ; + +gchar * cr_font_size_adjust_to_string (CRFontSizeAdjust const *a_this) ; + +void cr_font_size_adjust_destroy (CRFontSizeAdjust *a_this) ; + +void +cr_font_size_get_smaller_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_smaller_size) ; +void +cr_font_size_get_larger_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_larger_size) ; + +gboolean +cr_font_size_is_predefined_absolute_font_size (enum CRPredefinedAbsoluteFontSize a_font_size) ; + +/*********************************** + *various other font related functions + ***********************************/ +const gchar * cr_font_style_to_string (enum CRFontStyle a_code) ; + +const gchar * cr_font_weight_to_string (enum CRFontWeight a_code) ; + +enum CRFontWeight +cr_font_weight_get_bolder (enum CRFontWeight a_weight) ; + +const gchar * cr_font_variant_to_string (enum CRFontVariant a_code) ; + +const gchar * cr_font_stretch_to_string (enum CRFontStretch a_code) ; + +G_END_DECLS + +#endif diff --git a/src/3rdparty/libcroco/src/cr-input.c b/src/3rdparty/libcroco/src/cr-input.c new file mode 100644 index 0000000..645c4c5 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-input.c @@ -0,0 +1,1181 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "stdio.h" +#include <string.h> +#include "cr-input.h" +#include "cr-enc-handler.h" + +/** + *@CRInput: + * + *The definition of the #CRInput class. + */ + +/******************* + *Private type defs + *******************/ + +/** + *The private attributes of + *the #CRInputPriv class. + */ +struct _CRInputPriv { + /* + *The input buffer + */ + guchar *in_buf; + gulong in_buf_size; + + gulong nb_bytes; + + /* + *The index of the next byte + *to be read. + */ + gulong next_byte_index; + + /* + *The current line number + */ + gulong line; + + /* + *The current col number + */ + gulong col; + + gboolean end_of_line; + gboolean end_of_input; + + /* + *the reference count of this + *instance. + */ + guint ref_count; + gboolean free_in_buf; +}; + +#define PRIVATE(object) (object)->priv + +/*************************** + *private constants + **************************/ +#define CR_INPUT_MEM_CHUNK_SIZE 1024 * 4 + +static CRInput *cr_input_new_real (void); + +static CRInput * +cr_input_new_real (void) +{ + CRInput *result = NULL; + + result = g_try_malloc (sizeof (CRInput)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRInput)); + + PRIVATE (result) = g_try_malloc (sizeof (CRInputPriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRInputPriv)); + PRIVATE (result)->free_in_buf = TRUE; + return result; +} + +/**************** + *Public methods + ***************/ + +/** + * cr_input_new_from_buf: + *@a_buf: the memory buffer to create the input stream from. + *The #CRInput keeps this pointer so user should not free it !. + *@a_len: the size of the input buffer. + *@a_enc: the buffer's encoding. + *@a_free_buf: if set to TRUE, this a_buf will be freed + *at the destruction of this instance. If set to false, it is up + *to the caller to free it. + * + *Creates a new input stream from a memory buffer. + *Returns the newly built instance of #CRInput. + */ +CRInput * +cr_input_new_from_buf (guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) +{ + CRInput *result = NULL; + enum CRStatus status = CR_OK; + CREncHandler *enc_handler = NULL; + gulong len = a_len; + + g_return_val_if_fail (a_buf, NULL); + + result = cr_input_new_real (); + g_return_val_if_fail (result, NULL); + + /*transform the encoding in utf8 */ + if (a_enc != CR_UTF_8) { + enc_handler = cr_enc_handler_get_instance (a_enc); + if (!enc_handler) { + goto error; + } + + status = cr_enc_handler_convert_input + (enc_handler, a_buf, &len, + &PRIVATE (result)->in_buf, + &PRIVATE (result)->in_buf_size); + if (status != CR_OK) + goto error; + PRIVATE (result)->free_in_buf = TRUE; + if (a_free_buf == TRUE && a_buf) { + g_free (a_buf) ; + a_buf = NULL ; + } + PRIVATE (result)->nb_bytes = PRIVATE (result)->in_buf_size; + } else { + PRIVATE (result)->in_buf = (guchar *) a_buf; + PRIVATE (result)->in_buf_size = a_len; + PRIVATE (result)->nb_bytes = a_len; + PRIVATE (result)->free_in_buf = a_free_buf; + } + PRIVATE (result)->line = 1; + PRIVATE (result)->col = 0; + return result; + + error: + if (result) { + cr_input_destroy (result); + result = NULL; + } + + return NULL; +} + +/** + * cr_input_new_from_uri: + *@a_file_uri: the file to create *the input stream from. + *@a_enc: the encoding of the file *to create the input from. + * + *Creates a new input stream from + *a file. + * + *Returns the newly created input stream if + *this method could read the file and create it, + *NULL otherwise. + */ + +CRInput * +cr_input_new_from_uri (const gchar * a_file_uri, enum CREncoding a_enc) +{ + CRInput *result = NULL; + enum CRStatus status = CR_OK; + FILE *file_ptr = NULL; + guchar tmp_buf[CR_INPUT_MEM_CHUNK_SIZE] = { 0 }; + gulong nb_read = 0, + len = 0; + gboolean loop = TRUE; + guchar *buf = NULL; + + g_return_val_if_fail (a_file_uri, NULL); + + file_ptr = fopen (a_file_uri, "r"); + + if (file_ptr == NULL) { + +#ifdef CR_DEBUG + cr_utils_trace_debug ("could not open file"); +#endif + g_warning ("Could not open file %s\n", a_file_uri); + + return NULL; + } + + /*load the file */ + while (loop) { + nb_read = fread (tmp_buf, 1 /*read bytes */ , + CR_INPUT_MEM_CHUNK_SIZE /*nb of bytes */ , + file_ptr); + + if (nb_read != CR_INPUT_MEM_CHUNK_SIZE) { + /*we read less chars than we wanted */ + if (feof (file_ptr)) { + /*we reached eof */ + loop = FALSE; + } else { + /*a pb occurred !! */ + cr_utils_trace_debug ("an io error occurred"); + status = CR_ERROR; + goto cleanup; + } + } + + if (status == CR_OK) { + /*read went well */ + buf = g_realloc (buf, len + CR_INPUT_MEM_CHUNK_SIZE); + memcpy (buf + len, tmp_buf, nb_read); + len += nb_read; + } + } + + if (status == CR_OK) { + result = cr_input_new_from_buf (buf, len, a_enc, TRUE); + if (!result) { + goto cleanup; + } + /* + *we should free buf here because it's own by CRInput. + *(see the last parameter of cr_input_new_from_buf(). + */ + buf = NULL; + } + + cleanup: + if (file_ptr) { + fclose (file_ptr); + file_ptr = NULL; + } + + if (buf) { + g_free (buf); + buf = NULL; + } + + return result; +} + +/** + * cr_input_destroy: + *@a_this: the current instance of #CRInput. + * + *The destructor of the #CRInput class. + */ +void +cr_input_destroy (CRInput * a_this) +{ + if (a_this == NULL) + return; + + if (PRIVATE (a_this)) { + if (PRIVATE (a_this)->in_buf && PRIVATE (a_this)->free_in_buf) { + g_free (PRIVATE (a_this)->in_buf); + PRIVATE (a_this)->in_buf = NULL; + } + + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + g_free (a_this); +} + +/** + * cr_input_ref: + *@a_this: the current instance of #CRInput. + * + *Increments the reference count of the current + *instance of #CRInput. + */ +void +cr_input_ref (CRInput * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +/** + * cr_input_unref: + *@a_this: the current instance of #CRInput. + * + *Decrements the reference count of this instance + *of #CRInput. If the reference count goes down to + *zero, this instance is destroyed. + * + * Returns TRUE if the instance of #CRInput got destroyed, false otherwise. + */ +gboolean +cr_input_unref (CRInput * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), FALSE); + + if (PRIVATE (a_this)->ref_count) { + PRIVATE (a_this)->ref_count--; + } + + if (PRIVATE (a_this)->ref_count == 0) { + cr_input_destroy (a_this); + return TRUE; + } + return FALSE; +} + +/** + * cr_input_end_of_input: + *@a_this: the current instance of #CRInput. + *@a_end_of_input: out parameter. Is set to TRUE if + *the current instance has reached the end of its input buffer, + *FALSE otherwise. + * + *Tests whether the current instance of + *#CRInput has reached its input buffer. + * + * Returns CR_OK upon successful completion, an error code otherwise. + * Note that all the out parameters of this method are valid if + * and only if this method returns CR_OK. + */ +enum CRStatus +cr_input_end_of_input (CRInput const * a_this, gboolean * a_end_of_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_end_of_input, CR_BAD_PARAM_ERROR); + + *a_end_of_input = (PRIVATE (a_this)->next_byte_index + >= PRIVATE (a_this)->in_buf_size) ? TRUE : FALSE; + + return CR_OK; +} + +/** + * cr_input_get_nb_bytes_left: + *@a_this: the current instance of #CRInput. + * + *Returns the number of bytes left in the input stream + *before the end, -1 in case of error. + */ +glong +cr_input_get_nb_bytes_left (CRInput const * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), -1); + g_return_val_if_fail (PRIVATE (a_this)->nb_bytes + <= PRIVATE (a_this)->in_buf_size, -1); + g_return_val_if_fail (PRIVATE (a_this)->next_byte_index + <= PRIVATE (a_this)->nb_bytes, -1); + + if (PRIVATE (a_this)->end_of_input) + return 0; + + return PRIVATE (a_this)->nb_bytes - PRIVATE (a_this)->next_byte_index; +} + +/** + * cr_input_read_byte: + *@a_this: the current instance of #CRInput. + *@a_byte: out parameter the returned byte. + * + *Gets the next byte of the input. + *Updates the state of the input so that + *the next invocation of this method returns + *the next coming byte. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. All the out parameters of this method are valid if + *and only if this method returns CR_OK. + */ +enum CRStatus +cr_input_read_byte (CRInput * a_this, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_byte, CR_BAD_PARAM_ERROR); + + g_return_val_if_fail (PRIVATE (a_this)->next_byte_index <= + PRIVATE (a_this)->nb_bytes, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->end_of_input == TRUE) + return CR_END_OF_INPUT_ERROR; + + *a_byte = PRIVATE (a_this)->in_buf[PRIVATE (a_this)->next_byte_index]; + + if (PRIVATE (a_this)->nb_bytes - + PRIVATE (a_this)->next_byte_index < 2) { + PRIVATE (a_this)->end_of_input = TRUE; + } else { + PRIVATE (a_this)->next_byte_index++; + } + + return CR_OK; +} + +/** + * cr_input_read_char: + *@a_this: the current instance of CRInput. + *@a_char: out parameter. The read character. + * + *Reads an unicode character from the current instance of + *#CRInput. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_read_char (CRInput * a_this, guint32 * a_char) +{ + enum CRStatus status = CR_OK; + gulong consumed = 0, + nb_bytes_left = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_char, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->end_of_input == TRUE) + return CR_END_OF_INPUT_ERROR; + + nb_bytes_left = cr_input_get_nb_bytes_left (a_this); + + if (nb_bytes_left < 1) { + return CR_END_OF_INPUT_ERROR; + } + + status = cr_utils_read_char_from_utf8_buf + (PRIVATE (a_this)->in_buf + + + PRIVATE (a_this)->next_byte_index, + nb_bytes_left, a_char, &consumed); + + if (status == CR_OK) { + /*update next byte index */ + PRIVATE (a_this)->next_byte_index += consumed; + + /*update line and column number */ + if (PRIVATE (a_this)->end_of_line == TRUE) { + PRIVATE (a_this)->col = 1; + PRIVATE (a_this)->line++; + PRIVATE (a_this)->end_of_line = FALSE; + } else if (*a_char != '\n') { + PRIVATE (a_this)->col++; + } + + if (*a_char == '\n') { + PRIVATE (a_this)->end_of_line = TRUE; + } + } + + return status; +} + +/** + * cr_input_set_line_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_line_num: the new line number. + * + *Setter of the current line number. + * + *Return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_line_num (CRInput * a_this, glong a_line_num) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->line = a_line_num; + + return CR_OK; +} + +/** + * cr_input_get_line_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_line_num: the returned line number. + * + *Getter of the current line number. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_line_num (CRInput const * a_this, glong * a_line_num) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_line_num, CR_BAD_PARAM_ERROR); + + *a_line_num = PRIVATE (a_this)->line; + + return CR_OK; +} + +/** + * cr_input_set_column_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_col: the new column number. + * + *Setter of the current column number. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_column_num (CRInput * a_this, glong a_col) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->col = a_col; + + return CR_OK; +} + +/** + * cr_input_get_column_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_col: out parameter + * + *Getter of the current column number. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_column_num (CRInput const * a_this, glong * a_col) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_col, + CR_BAD_PARAM_ERROR); + + *a_col = PRIVATE (a_this)->col; + + return CR_OK; +} + +/** + * cr_input_increment_line_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_increment: the increment to add to the line number. + * + *Increments the current line number. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_increment_line_num (CRInput * a_this, glong a_increment) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->line += a_increment; + + return CR_OK; +} + +/** + * cr_input_increment_col_num: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_increment: the increment to add to the column number. + * + *Increments the current column number. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_increment_col_num (CRInput * a_this, glong a_increment) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->col += a_increment; + + return CR_OK; +} + +/** + * cr_input_consume_char: + *@a_this: the this pointer. + *@a_char: the character to consume. If set to zero, + *consumes any character. + * + *Consumes the next character of the input stream if + *and only if that character equals a_char. + * + *Returns CR_OK upon successful completion, CR_PARSING_ERROR if + *next char is different from a_char, an other error code otherwise + */ +enum CRStatus +cr_input_consume_char (CRInput * a_this, guint32 a_char) +{ + guint32 c; + enum CRStatus status; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if ((status = cr_input_peek_char (a_this, &c)) != CR_OK) { + return status; + } + + if (c == a_char || a_char == 0) { + status = cr_input_read_char (a_this, &c); + } else { + return CR_PARSING_ERROR; + } + + return status; +} + +/** + * cr_input_consume_chars: + *@a_this: the this pointer of the current instance of #CRInput. + *@a_char: the character to consume. + *@a_nb_char: in/out parameter. The number of characters to consume. + *If set to a negative value, the function will consume all the occurrences + *of a_char found. + *After return, if the return value equals CR_OK, this variable contains + *the number of characters actually consumed. + * + *Consumes up to a_nb_char occurrences of the next contiguous characters + *which equal a_char. Note that the next character of the input stream + **MUST* equal a_char to trigger the consumption, or else, the error + *code CR_PARSING_ERROR is returned. + *If the number of contiguous characters that equals a_char is less than + *a_nb_char, then this function consumes all the characters it can consume. + * + *Returns CR_OK if at least one character has been consumed, an error code + *otherwise. + */ +enum CRStatus +cr_input_consume_chars (CRInput * a_this, guint32 a_char, gulong * a_nb_char) +{ + enum CRStatus status = CR_OK; + gulong nb_consumed = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_nb_char, + CR_BAD_PARAM_ERROR); + + g_return_val_if_fail (a_char != 0 || a_nb_char != NULL, + CR_BAD_PARAM_ERROR); + + for (nb_consumed = 0; ((status == CR_OK) + && (*a_nb_char > 0 + && nb_consumed < *a_nb_char)); + nb_consumed++) { + status = cr_input_consume_char (a_this, a_char); + } + + *a_nb_char = nb_consumed; + + if ((nb_consumed > 0) + && ((status == CR_PARSING_ERROR) + || (status == CR_END_OF_INPUT_ERROR))) { + status = CR_OK; + } + + return status; +} + +/** + * cr_input_consume_white_spaces: + *@a_this: the "this pointer" of the current instance of #CRInput. + *@a_nb_chars: in/out parameter. The number of white spaces to + *consume. After return, holds the number of white spaces actually consumed. + * + *Same as cr_input_consume_chars() but this one consumes white + *spaces. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_consume_white_spaces (CRInput * a_this, gulong * a_nb_chars) +{ + enum CRStatus status = CR_OK; + guint32 cur_char = 0, + nb_consumed = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_nb_chars, + CR_BAD_PARAM_ERROR); + + for (nb_consumed = 0; + ((*a_nb_chars > 0) && (nb_consumed < *a_nb_chars)); + nb_consumed++) { + status = cr_input_peek_char (a_this, &cur_char); + if (status != CR_OK) + break; + + /*if the next char is a white space, consume it ! */ + if (cr_utils_is_white_space (cur_char) == TRUE) { + status = cr_input_read_char (a_this, &cur_char); + if (status != CR_OK) + break; + continue; + } + + break; + + } + + *a_nb_chars = (gulong) nb_consumed; + + if (nb_consumed && status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + } + + return status; +} + +/** + * cr_input_peek_char: + *@a_this: the current instance of #CRInput. + *@a_char: out parameter. The returned character. + * + *Same as cr_input_read_char() but does not update the + *internal state of the input stream. The next call + *to cr_input_peek_char() or cr_input_read_char() will thus + *return the same character as the current one. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_peek_char (CRInput const * a_this, guint32 * a_char) +{ + enum CRStatus status = CR_OK; + gulong consumed = 0, + nb_bytes_left = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->next_byte_index >= + PRIVATE (a_this)->in_buf_size) { + return CR_END_OF_INPUT_ERROR; + } + + nb_bytes_left = cr_input_get_nb_bytes_left (a_this); + + if (nb_bytes_left < 1) { + return CR_END_OF_INPUT_ERROR; + } + + status = cr_utils_read_char_from_utf8_buf + (PRIVATE (a_this)->in_buf + + PRIVATE (a_this)->next_byte_index, + nb_bytes_left, a_char, &consumed); + + return status; +} + +/** + * cr_input_peek_byte: + *@a_this: the current instance of #CRInput. + *@a_origin: the origin to consider in the calculation + *of the position of the byte to peek. + *@a_offset: the offset of the byte to peek, starting from + *the origin specified by a_origin. + *@a_byte: out parameter the peeked byte. + * + *Gets a byte from the input stream, + *starting from the current position in the input stream. + *Unlike cr_input_peek_next_byte() this method + *does not update the state of the current input stream. + *Subsequent calls to cr_input_peek_byte with the same arguments + *will return the same byte. + * + *Returns CR_OK upon successful completion or, + *CR_BAD_PARAM_ERROR if at least one of the parameters is invalid; + *CR_OUT_OF_BOUNDS_ERROR if the indexed byte is out of bounds. + */ +enum CRStatus +cr_input_peek_byte (CRInput const * a_this, enum CRSeekPos a_origin, + gulong a_offset, guchar * a_byte) +{ + gulong abs_offset = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_byte, CR_BAD_PARAM_ERROR); + + switch (a_origin) { + + case CR_SEEK_CUR: + abs_offset = PRIVATE (a_this)->next_byte_index - 1 + a_offset; + break; + + case CR_SEEK_BEGIN: + abs_offset = a_offset; + break; + + case CR_SEEK_END: + abs_offset = PRIVATE (a_this)->in_buf_size - 1 - a_offset; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if (abs_offset < PRIVATE (a_this)->in_buf_size) { + + *a_byte = PRIVATE (a_this)->in_buf[abs_offset]; + + return CR_OK; + + } else { + return CR_END_OF_INPUT_ERROR; + } +} + +/** + * cr_input_peek_byte2: + *@a_this: the current byte input stream. + *@a_offset: the offset of the byte to peek, starting + *from the current input position pointer. + *@a_eof: out parameter. Is set to true is we reach end of + *stream. If set to NULL by the caller, this parameter is not taken + *in account. + * + *Same as cr_input_peek_byte() but with a simplified + *interface. + * + *Returns the read byte or 0 if something bad happened. + */ +guchar +cr_input_peek_byte2 (CRInput const * a_this, gulong a_offset, gboolean * a_eof) +{ + guchar result = 0; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), 0); + + if (a_eof) + *a_eof = FALSE; + + status = cr_input_peek_byte (a_this, CR_SEEK_CUR, a_offset, &result); + + if ((status == CR_END_OF_INPUT_ERROR) + && a_eof) + *a_eof = TRUE; + + return result; +} + +/** + * cr_input_get_byte_addr: + *@a_this: the current instance of #CRInput. + *@a_offset: the offset of the byte in the input stream starting + *from the beginning of the stream. + * + *Gets the memory address of the byte located at a given offset + *in the input stream. + * + *Returns the address, otherwise NULL if an error occurred. + */ +guchar * +cr_input_get_byte_addr (CRInput * a_this, gulong a_offset) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + if (a_offset >= PRIVATE (a_this)->nb_bytes) { + return NULL; + } + + return &PRIVATE (a_this)->in_buf[a_offset]; +} + +/** + * cr_input_get_cur_byte_addr: + *@a_this: the current input stream + *@a_offset: out parameter. The returned address. + * + *Gets the address of the current character pointer. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_cur_byte_addr (CRInput * a_this, guchar ** a_offset) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_offset, + CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->next_byte_index) { + return CR_START_OF_INPUT_ERROR; + } + + *a_offset = cr_input_get_byte_addr + (a_this, PRIVATE (a_this)->next_byte_index - 1); + + return CR_OK; +} + +/** + * cr_input_seek_index: + *@a_this: the current instance of #CRInput. + *@a_origin: the origin to consider during the calculation + *of the absolute position of the new "current byte index". + *@a_pos: the relative offset of the new "current byte index." + *This offset is relative to the origin a_origin. + * + *Sets the "current byte index" of the current instance + *of #CRInput. Next call to cr_input_get_byte() will return + *the byte next after the new "current byte index". + * + *Returns CR_OK upon successful completion otherwise returns + *CR_BAD_PARAM_ERROR if at least one of the parameters is not valid + *or CR_OUT_BOUNDS_ERROR in case of error. + */ +enum CRStatus +cr_input_seek_index (CRInput * a_this, enum CRSeekPos a_origin, gint a_pos) +{ + + glong abs_offset = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + switch (a_origin) { + + case CR_SEEK_CUR: + abs_offset = PRIVATE (a_this)->next_byte_index - 1 + a_pos; + break; + + case CR_SEEK_BEGIN: + abs_offset = a_pos; + break; + + case CR_SEEK_END: + abs_offset = PRIVATE (a_this)->in_buf_size - 1 - a_pos; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if ((abs_offset > 0) + && (gulong) abs_offset < PRIVATE (a_this)->nb_bytes) { + + /*update the input stream's internal state */ + PRIVATE (a_this)->next_byte_index = abs_offset + 1; + + return CR_OK; + } + + return CR_OUT_OF_BOUNDS_ERROR; +} + +/** + * cr_input_get_cur_pos: + *@a_this: the current instance of #CRInput. + *@a_pos: out parameter. The returned position. + * + *Gets the position of the "current byte index" which + *is basically the position of the last returned byte in the + *input stream. + * + *Returns CR_OK upon successful completion. Otherwise, + *CR_BAD_PARAMETER_ERROR if at least one of the arguments is invalid. + *CR_START_OF_INPUT if no call to either cr_input_read_byte() + *or cr_input_seek_index() have been issued before calling + *cr_input_get_cur_pos() + *Note that the out parameters of this function are valid if and only if this + *function returns CR_OK. + */ +enum CRStatus +cr_input_get_cur_pos (CRInput const * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pos, + CR_BAD_PARAM_ERROR); + + a_pos->next_byte_index = PRIVATE (a_this)->next_byte_index; + a_pos->line = PRIVATE (a_this)->line; + a_pos->col = PRIVATE (a_this)->col; + a_pos->end_of_line = PRIVATE (a_this)->end_of_line; + a_pos->end_of_file = PRIVATE (a_this)->end_of_input; + + return CR_OK; +} + +/** + * cr_input_get_parsing_location: + *@a_this: the current instance of #CRInput + *@a_loc: the set parsing location. + * + *Gets the current parsing location. + *The Parsing location is a public datastructure that + *represents the current line/column/byte offset/ in the input + *stream. + * + *Returns CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_input_get_parsing_location (CRInput const *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, + CR_BAD_PARAM_ERROR) ; + + a_loc->line = PRIVATE (a_this)->line ; + a_loc->column = PRIVATE (a_this)->col ; + if (PRIVATE (a_this)->next_byte_index) { + a_loc->byte_offset = PRIVATE (a_this)->next_byte_index - 1 ; + } else { + a_loc->byte_offset = PRIVATE (a_this)->next_byte_index ; + } + return CR_OK ; +} + +/** + * cr_input_get_cur_index: + *@a_this: the "this pointer" of the current instance of + *#CRInput + *@a_index: out parameter. The returned index. + * + *Getter of the next byte index. + *It actually returns the index of the + *next byte to be read. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_get_cur_index (CRInput const * a_this, glong * a_index) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_index, CR_BAD_PARAM_ERROR); + + *a_index = PRIVATE (a_this)->next_byte_index; + + return CR_OK; +} + +/** + * cr_input_set_cur_index: + *@a_this: the "this pointer" of the current instance + *of #CRInput . + *@a_index: the new index to set. + * + *Setter of the next byte index. + *It sets the index of the next byte to be read. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_cur_index (CRInput * a_this, glong a_index) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->next_byte_index = a_index; + + return CR_OK; +} + +/** + * cr_input_set_end_of_file: + *@a_this: the current instance of #CRInput. + *@a_eof: the new end of file flag. + * + *Sets the end of file flag. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_end_of_file (CRInput * a_this, gboolean a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->end_of_input = a_eof; + + return CR_OK; +} + +/** + * cr_input_get_end_of_file: + *@a_this: the current instance of #CRInput. + *@a_eof: out parameter the place to put the end of + *file flag. + * + *Gets the end of file flag. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_end_of_file (CRInput const * a_this, gboolean * a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_eof, CR_BAD_PARAM_ERROR); + + *a_eof = PRIVATE (a_this)->end_of_input; + + return CR_OK; +} + +/** + * cr_input_set_end_of_line: + *@a_this: the current instance of #CRInput. + *@a_eol: the new end of line flag. + * + *Sets the end of line flag. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_set_end_of_line (CRInput * a_this, gboolean a_eol) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->end_of_line = a_eol; + + return CR_OK; +} + +/** + * cr_input_get_end_of_line: + *@a_this: the current instance of #CRInput + *@a_eol: out parameter. The place to put + *the returned flag + * + *Gets the end of line flag of the current input. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_get_end_of_line (CRInput const * a_this, gboolean * a_eol) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_eol, CR_BAD_PARAM_ERROR); + + *a_eol = PRIVATE (a_this)->end_of_line; + + return CR_OK; +} + +/** + * cr_input_set_cur_pos: + *@a_this: the "this pointer" of the current instance of + *#CRInput. + *@a_pos: the new position. + * + *Sets the current position in the input stream. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_cur_pos (CRInput * a_this, CRInputPos const * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pos, + CR_BAD_PARAM_ERROR); + + cr_input_set_column_num (a_this, a_pos->col); + cr_input_set_line_num (a_this, a_pos->line); + cr_input_set_cur_index (a_this, a_pos->next_byte_index); + cr_input_set_end_of_line (a_this, a_pos->end_of_line); + cr_input_set_end_of_file (a_this, a_pos->end_of_file); + + return CR_OK; +} diff --git a/src/3rdparty/libcroco/src/cr-input.h b/src/3rdparty/libcroco/src/cr-input.h new file mode 100644 index 0000000..9eb402a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-input.h @@ -0,0 +1,174 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_INPUT_SRC_H__ +#define __CR_INPUT_SRC_H__ + + +#include <glib.h> +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The libcroco basic input stream class + *declaration file. + */ + +typedef struct _CRInput CRInput ; +typedef struct _CRInputPriv CRInputPriv ; + +/** + *The #CRInput class provides the abstraction of + *an utf8-encoded character stream. + */ +struct _CRInput +{ + CRInputPriv *priv ; +} ; + +typedef struct _CRInputPos CRInputPos ; + +struct _CRInputPos +{ + glong line ; + glong col ; + gboolean end_of_file ; + gboolean end_of_line ; + glong next_byte_index ; +} ; + +CRInput * +cr_input_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, gboolean a_free_buf) ; +CRInput * +cr_input_new_from_uri (const gchar *a_file_uri, + enum CREncoding a_enc) ; + +void +cr_input_destroy (CRInput *a_this) ; + +void +cr_input_ref (CRInput *a_this) ; + +gboolean +cr_input_unref (CRInput *a_this) ; + +enum CRStatus +cr_input_read_byte (CRInput *a_this, guchar *a_byte) ; + +enum CRStatus +cr_input_read_char (CRInput *a_this, guint32 *a_char) ; + +enum CRStatus +cr_input_consume_chars (CRInput *a_this, guint32 a_char, + gulong *a_nb_char) ; + +enum CRStatus +cr_input_consume_char (CRInput *a_this, guint32 a_char) ; + +enum CRStatus +cr_input_consume_white_spaces (CRInput *a_this, gulong *a_nb_chars) ; + +enum CRStatus +cr_input_peek_byte (CRInput const *a_this, enum CRSeekPos a_origin, + gulong a_offset, guchar *a_byte) ; + +guchar +cr_input_peek_byte2 (CRInput const *a_this, gulong a_offset, + gboolean *a_eof) ; + +enum CRStatus +cr_input_peek_char (CRInput const *a_this, guint32 *a_char) ; + +guchar * +cr_input_get_byte_addr (CRInput *a_this, + gulong a_offset) ; + +enum CRStatus +cr_input_get_cur_byte_addr (CRInput *a_this, guchar ** a_offset) ; + +enum CRStatus +cr_input_seek_index (CRInput *a_this, + enum CRSeekPos a_origin, gint a_pos) ; + +enum CRStatus +cr_input_get_cur_index (CRInput const *a_this, glong *a_index) ; + +enum CRStatus +cr_input_set_cur_index (CRInput *a_this, glong a_index) ; + +enum CRStatus +cr_input_get_cur_pos (CRInput const *a_this, CRInputPos * a_pos) ; + +enum CRStatus +cr_input_set_cur_pos (CRInput *a_this, CRInputPos const *a_pos) ; + +enum CRStatus +cr_input_get_parsing_location (CRInput const *a_this, + CRParsingLocation *a_loc) ; + +enum CRStatus +cr_input_get_end_of_line (CRInput const *a_this, gboolean *a_eol) ; + +enum CRStatus +cr_input_set_end_of_line (CRInput *a_this, gboolean a_eol) ; + +enum CRStatus +cr_input_get_end_of_file (CRInput const *a_this, gboolean *a_eof) ; + +enum CRStatus +cr_input_set_end_of_file (CRInput *a_this, gboolean a_eof) ; + +enum CRStatus +cr_input_set_line_num (CRInput *a_this, glong a_line_num) ; + +enum CRStatus +cr_input_get_line_num (CRInput const *a_this, glong *a_line_num) ; + +enum CRStatus +cr_input_set_column_num (CRInput *a_this, glong a_col) ; + +enum CRStatus +cr_input_get_column_num (CRInput const *a_this, glong *a_col) ; + +enum CRStatus +cr_input_increment_line_num (CRInput *a_this, + glong a_increment) ; + +enum CRStatus +cr_input_increment_col_num (CRInput *a_this, + glong a_increment) ; + +glong +cr_input_get_nb_bytes_left (CRInput const *a_this) ; + +enum CRStatus +cr_input_end_of_input (CRInput const *a_this, gboolean *a_end_of_input) ; + +G_END_DECLS + +#endif /*__CR_INPUT_SRC_H__*/ + diff --git a/src/3rdparty/libcroco/src/cr-libxml-node-iface.c b/src/3rdparty/libcroco/src/cr-libxml-node-iface.c new file mode 100644 index 0000000..bc860f9 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-libxml-node-iface.c @@ -0,0 +1,81 @@ +#include <libxml/tree.h> +#include <string.h> +#include "cr-libxml-node-iface.h" + +static CRXMLNodePtr +libxml_getParentNode(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->parent; +} + +static CRXMLNodePtr +libxml_getFirstChild(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->children; +} + +static CRXMLNodePtr +libxml_getNextSibling(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->next; +} + +static CRXMLNodePtr +libxml_getPrevSibling(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->prev; +} + +static char const * +local_part(char const *const qname) +{ + char const *ret = strrchr(qname, ':'); + if (ret) + return ++ret; + else + return qname; +} + +static char const * +libxml_getLocalName(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return local_part((char *)xnode->name); +} + +static char * +libxml_getProp(CRXMLNodePtr cnode, char const *cprop) +{ + xmlNodePtr xnode = (xmlNodePtr) cnode; + xmlChar const *xprop = (xmlChar const *) cprop; + return (char *)xmlGetProp(xnode, xprop); +} + +static gboolean +libxml_isElementNode(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->type == XML_ELEMENT_NODE; +} + +static void +libxml_freePropVal(void *const cval) +{ + xmlFree(cval); +} + +CRNodeIface const cr_libxml_node_iface = { + libxml_getParentNode, + libxml_getFirstChild, + libxml_getNextSibling, + libxml_getPrevSibling, + libxml_getLocalName, + libxml_getProp, /* fixme: Check whether we want xmlGetNoNsProp instead. */ + + libxml_freePropVal, + libxml_isElementNode +}; diff --git a/src/3rdparty/libcroco/src/cr-libxml-node-iface.h b/src/3rdparty/libcroco/src/cr-libxml-node-iface.h new file mode 100644 index 0000000..b4a6212 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-libxml-node-iface.h @@ -0,0 +1,14 @@ +#ifndef __CR_LIBXML_NODE_IFACE_H__ +#define __CR_LIBXML_NODE_IFACE_H__ + +#include <glib.h> +#include "cr-node-iface.h" + +G_BEGIN_DECLS + +extern CRNodeIface const cr_libxml_node_iface; + +G_END_DECLS + + +#endif/*__CR_LIBXML_NODE_IFACE_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-node-iface.h b/src/3rdparty/libcroco/src/cr-node-iface.h new file mode 100644 index 0000000..01898d6 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-node-iface.h @@ -0,0 +1,34 @@ +#ifndef __CR_NODE_IFACE_H__ +#define __CR_NODE_IFACE_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +typedef gconstpointer CRXMLNodePtr ; +typedef struct _CRNodeIface CRNodeIface ; + +struct _CRNodeIface { + /* Names based on DOM. */ + CRXMLNodePtr (*getParentNode)(CRXMLNodePtr); + CRXMLNodePtr (*getFirstChild)(CRXMLNodePtr); + CRXMLNodePtr (*getNextSibling)(CRXMLNodePtr); + CRXMLNodePtr (*getPrevSibling)(CRXMLNodePtr); + char const *(*getLocalName)(CRXMLNodePtr); + char *(*getProp)(CRXMLNodePtr, char const *); + + /* Others. */ + void (*freePropVal)(void *); + gboolean (*isElementNode)(CRXMLNodePtr); + +#if 0 + char const *getLang(CRXMLNodePtr); + /* todo: Make it easy to have the default xml rules for lang. Maybe interpret NULL + like this. Or provide a cr_get_xml_lang(CRNodeIface const *, CRXMLNodePtr) function. */ +#endif +}; + +G_END_DECLS + + +#endif/*__CR_NODE_IFACE_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-num.c b/src/3rdparty/libcroco/src/cr-num.c new file mode 100644 index 0000000..12da520 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-num.c @@ -0,0 +1,345 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +/** + *@CRNum: + * + *The definition + *of the #CRNum class. + */ + +#include "cr-num.h" +#include "string.h" + +#include <float.h> +#include <math.h> +#include <stdio.h> + +/** + * cr_num_new: + * + *#CRNum. + * + *Returns the newly built instance of + *#CRNum. + */ +CRNum * +cr_num_new (void) +{ + CRNum *result = NULL; + + result = g_try_malloc (sizeof (CRNum)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRNum)); + + return result; +} + +/** + * cr_num_new_with_val: + * @a_val: the numerical value of the number. + * @a_type: the type of number. + * + * A constructor of #CRNum. + * + * Returns the newly built instance of #CRNum or + * NULL if an error arises. + */ +CRNum * +cr_num_new_with_val (gdouble a_val, enum CRNumType a_type) +{ + CRNum *result = NULL; + + result = cr_num_new (); + + g_return_val_if_fail (result, NULL); + + result->val = a_val; + result->type = a_type; + + return result; +} + + +/** + * Like g_ascii_dtostr() but uses not more than DBL_DIG significant digits + * to avoid results like "1.0000000000000001". + */ +static void +pretty_ascii_dtostr (gchar *buffer, gint buf_len, gdouble d) +{ + gint digits = DBL_DIG - ceil (log10 (fabs (d))); + gchar format[8] = "%."; + sprintf (format + 2, "%df", CLAMP (digits, 0, 9999)); + + g_ascii_formatd (buffer, buf_len, format, d); + + // strip trailing zeros and trailing dot + if (strchr (buffer, '.') != NULL) { + gsize pos = strlen (buffer) - 1; + while (buffer[pos] == '0') { + --pos; + } + if (buffer[pos] == '.') { + --pos; + } + buffer[pos + 1] = '\0'; + } +} + +/** + * cr_num_to_string: + *@a_this: the current instance of #CRNum. + * + *Returns the newly built string representation + *of the current instance of #CRNum. The returned + *string is NULL terminated. The caller *must* + *free the returned string. + */ +guchar * +cr_num_to_string (CRNum const * a_this) +{ + gdouble test_val = 0.0; + + guchar *tmp_char1 = NULL, + *tmp_char2 = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + test_val = a_this->val - (glong) a_this->val; + + if (!test_val) { + tmp_char1 = (guchar *) g_strdup_printf ("%ld", (glong) a_this->val); + } else { + tmp_char1 = (guchar *) g_new0 (char, G_ASCII_DTOSTR_BUF_SIZE + 1); + if (tmp_char1 != NULL) + pretty_ascii_dtostr ((gchar *) tmp_char1, G_ASCII_DTOSTR_BUF_SIZE, a_this->val); + } + + g_return_val_if_fail (tmp_char1, NULL); + + switch (a_this->type) { + case NUM_LENGTH_EM: + tmp_char2 = (guchar *) "em"; + break; + + case NUM_LENGTH_EX: + tmp_char2 = (guchar *) "ex"; + break; + + case NUM_LENGTH_PX: + tmp_char2 = (guchar *) "px"; + break; + + case NUM_LENGTH_IN: + tmp_char2 = (guchar *) "in"; + break; + + case NUM_LENGTH_CM: + tmp_char2 = (guchar *) "cm"; + break; + + case NUM_LENGTH_MM: + tmp_char2 = (guchar *) "mm"; + break; + + case NUM_LENGTH_PT: + tmp_char2 = (guchar *) "pt"; + break; + + case NUM_LENGTH_PC: + tmp_char2 = (guchar *) "pc"; + break; + + case NUM_ANGLE_DEG: + tmp_char2 = (guchar *) "deg"; + break; + + case NUM_ANGLE_RAD: + tmp_char2 = (guchar *) "rad"; + break; + + case NUM_ANGLE_GRAD: + tmp_char2 = (guchar *) "grad"; + break; + + case NUM_TIME_MS: + tmp_char2 = (guchar *) "ms"; + break; + + case NUM_TIME_S: + tmp_char2 = (guchar *) "s"; + break; + + case NUM_FREQ_HZ: + tmp_char2 = (guchar *) "Hz"; + break; + + case NUM_FREQ_KHZ: + tmp_char2 = (guchar *) "KHz"; + break; + + case NUM_PERCENTAGE: + tmp_char2 = (guchar *) "%"; + break; + case NUM_INHERIT: + tmp_char2 = (guchar *) "inherit"; + break ; + case NUM_AUTO: + tmp_char2 = (guchar *) "auto"; + break ; + case NUM_GENERIC: + tmp_char2 = NULL ; + break ; + default: + tmp_char2 = (guchar *) "unknown"; + break; + } + + if (tmp_char2) { + result = (guchar *) g_strconcat ((gchar *) tmp_char1, tmp_char2, NULL); + g_free (tmp_char1); + } else { + result = tmp_char1; + } + + return result; +} + +/** + * cr_num_copy: + *@a_src: the instance of #CRNum to copy. + *Must be non NULL. + *@a_dest: the destination of the copy. + *Must be non NULL + * + *Copies an instance of #CRNum. + * + *Returns CR_OK upon successful completion, an + *error code otherwise. + */ +enum CRStatus +cr_num_copy (CRNum * a_dest, CRNum const * a_src) +{ + g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR); + + memcpy (a_dest, a_src, sizeof (CRNum)); + + return CR_OK; +} + +/** + * cr_num_dup: + *@a_this: the instance of #CRNum to duplicate. + * + *Duplicates an instance of #CRNum + * + *Returns the newly created (duplicated) instance of #CRNum. + *Must be freed by cr_num_destroy(). + */ +CRNum * +cr_num_dup (CRNum const * a_this) +{ + CRNum *result = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this, NULL); + + result = cr_num_new (); + g_return_val_if_fail (result, NULL); + + status = cr_num_copy (result, a_this); + if (status != CR_OK) + g_clear_pointer (&result, cr_num_destroy); + + return result; +} + +/** + * cr_num_set: + *Sets an instance of #CRNum. + *@a_this: the current instance of #CRNum to be set. + *@a_val: the new numerical value to be hold by the current + *instance of #CRNum + *@a_type: the new type of #CRNum. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->val = a_val; + a_this->type = a_type; + + return CR_OK; +} + +/** + * cr_num_is_fixed_length: + * @a_this: the current instance of #CRNum . + * + *Tests if the current instance of #CRNum is a fixed + *length value or not. Typically a fixed length value + *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC. + *See the definition of #CRNumType to see what we mean. + * + *Returns TRUE if the instance of #CRNum is a fixed length number, + *FALSE otherwise. + */ +gboolean +cr_num_is_fixed_length (CRNum const * a_this) +{ + gboolean result = FALSE; + + g_return_val_if_fail (a_this, FALSE); + + if (a_this->type >= NUM_LENGTH_EM + && a_this->type <= NUM_LENGTH_PC) { + result = TRUE ; + } + return result ; +} + +/** + * cr_num_destroy: + *@a_this: the this pointer of + *the current instance of #CRNum. + * + *The destructor of #CRNum. + */ +void +cr_num_destroy (CRNum * a_this) +{ + g_return_if_fail (a_this); + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-num.h b/src/3rdparty/libcroco/src/cr-num.h new file mode 100644 index 0000000..2b73aaf --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-num.h @@ -0,0 +1,127 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information + */ + + +/** + *@file + *The declaration + *of the #CRNum class. + */ + +#ifndef __CR_NUM_H__ +#define __CR_NUM_H__ + +#include <glib.h> +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRNum class. + * + */ + +/** + *The different types + *of numbers. + *Please, do not modify + *the declaration order of the enum + *members, unless you know + *what you are doing. + */ +enum CRNumType +{ + NUM_AUTO = 0, + NUM_GENERIC, + NUM_LENGTH_EM, + NUM_LENGTH_EX, + NUM_LENGTH_PX, + NUM_LENGTH_IN, + NUM_LENGTH_CM, + NUM_LENGTH_MM, + NUM_LENGTH_PT, + NUM_LENGTH_PC, + NUM_ANGLE_DEG, + NUM_ANGLE_RAD, + NUM_ANGLE_GRAD, + NUM_TIME_MS, + NUM_TIME_S, + NUM_FREQ_HZ, + NUM_FREQ_KHZ, + NUM_PERCENTAGE, + NUM_INHERIT, + NUM_UNKNOWN_TYPE, + NB_NUM_TYPE +} ; + + +/** + *An abstraction of a number (num) + *as defined in the css2 spec. + */ +typedef struct _CRNum CRNum ; + +/** + *An abstraction of a number (num) + *as defined in the css2 spec. + */ +struct _CRNum +{ + enum CRNumType type ; + gdouble val ; + CRParsingLocation location ; +} ; + +CRNum * +cr_num_new (void) ; + +CRNum * +cr_num_new_with_val (gdouble a_val, + enum CRNumType a_type) ; + +CRNum * +cr_num_dup (CRNum const *a_this) ; + +guchar * +cr_num_to_string (CRNum const *a_this) ; + +enum CRStatus +cr_num_copy (CRNum *a_dest, CRNum const *a_src) ; + +enum CRStatus +cr_num_set (CRNum *a_this, gdouble a_val, + enum CRNumType a_type) ; + +gboolean +cr_num_is_fixed_length (CRNum const *a_this) ; + +void +cr_num_destroy (CRNum *a_this) ; + + +G_END_DECLS + + +#endif /*__CR_NUM_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-om-parser.c b/src/3rdparty/libcroco/src/cr-om-parser.c new file mode 100644 index 0000000..3b0ae26 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-om-parser.c @@ -0,0 +1,1150 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-utils.h" +#include "cr-om-parser.h" + +/** + *@CROMParser: + * + *The definition of the CSS Object Model Parser. + *This parser uses (and sits) the SAC api of libcroco defined + *in cr-parser.h and cr-doc-handler.h + */ + +struct _CROMParserPriv { + CRParser *parser; +}; + +#define PRIVATE(a_this) ((a_this)->priv) + +/* + *Forward declaration of a type defined later + *in this file. + */ +struct _ParsingContext; +typedef struct _ParsingContext ParsingContext; + +static ParsingContext *new_parsing_context (void); + +static void destroy_context (ParsingContext * a_ctxt); + +static void unrecoverable_error (CRDocHandler * a_this); + +static void error (CRDocHandler * a_this); + +static void property (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, + gboolean a_important); + +static void end_selector (CRDocHandler * a_this, + CRSelector * a_selector_list); + +static void start_selector (CRDocHandler * a_this, + CRSelector * a_selector_list); + +static void start_font_face (CRDocHandler * a_this, + CRParsingLocation *a_location); + +static void end_font_face (CRDocHandler * a_this); + +static void end_document (CRDocHandler * a_this); + +static void start_document (CRDocHandler * a_this); + +static void charset (CRDocHandler * a_this, + CRString * a_charset, + CRParsingLocation *a_location); + +static void start_page (CRDocHandler * a_this, CRString * a_page, + CRString * a_pseudo_page, + CRParsingLocation *a_location); + +static void end_page (CRDocHandler * a_this, CRString * a_page, + CRString * a_pseudo_page); + +static void start_media (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation *a_location); + +static void end_media (CRDocHandler * a_this, + GList * a_media_list); + +static void import_style (CRDocHandler * a_this, + GList * a_media_list, + CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location); + +struct _ParsingContext { + CRStyleSheet *stylesheet; + CRStatement *cur_stmt; + CRStatement *cur_media_stmt; +}; + +/******************************************** + *Private methods + ********************************************/ + +static ParsingContext * +new_parsing_context (void) +{ + ParsingContext *result = NULL; + + result = g_try_malloc (sizeof (ParsingContext)); + if (!result) { + cr_utils_trace_info ("Out of Memory"); + return NULL; + } + memset (result, 0, sizeof (ParsingContext)); + return result; +} + +static void +destroy_context (ParsingContext * a_ctxt) +{ + g_return_if_fail (a_ctxt); + + if (a_ctxt->stylesheet) { + cr_stylesheet_destroy (a_ctxt->stylesheet); + a_ctxt->stylesheet = NULL; + } + if (a_ctxt->cur_stmt) { + cr_statement_destroy (a_ctxt->cur_stmt); + a_ctxt->cur_stmt = NULL; + } + g_free (a_ctxt); +} + +static enum CRStatus +cr_om_parser_init_default_sac_handler (CROMParser * a_this) +{ + CRDocHandler *sac_handler = NULL; + gboolean created_handler = FALSE; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->parser, + CR_BAD_PARAM_ERROR); + + status = cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (status == CR_OK, status); + + if (!sac_handler) { + sac_handler = cr_doc_handler_new (); + created_handler = TRUE; + } + + /* + *initialize here the sac handler. + */ + sac_handler->start_document = start_document; + sac_handler->end_document = end_document; + sac_handler->start_selector = start_selector; + sac_handler->end_selector = end_selector; + sac_handler->property = property; + sac_handler->start_font_face = start_font_face; + sac_handler->end_font_face = end_font_face; + sac_handler->error = error; + sac_handler->unrecoverable_error = unrecoverable_error; + sac_handler->charset = charset; + sac_handler->start_page = start_page; + sac_handler->end_page = end_page; + sac_handler->start_media = start_media; + sac_handler->end_media = end_media; + sac_handler->import_style = import_style; + + if (created_handler) { + status = cr_parser_set_sac_handler (PRIVATE (a_this)->parser, + sac_handler); + cr_doc_handler_unref (sac_handler); + } + + return status; + +} + +static void +start_document (CRDocHandler * a_this) +{ + ParsingContext *ctxt = NULL; + CRStyleSheet *stylesheet = NULL; + + g_return_if_fail (a_this); + + ctxt = new_parsing_context (); + g_return_if_fail (ctxt); + + stylesheet = cr_stylesheet_new (NULL); + ctxt->stylesheet = stylesheet; + cr_doc_handler_set_ctxt (a_this, ctxt); +} + +static void +start_font_face (CRDocHandler * a_this, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + (void) a_location; + + g_return_if_fail (a_this); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt == NULL); + + ctxt->cur_stmt = + cr_statement_new_at_font_face_rule (ctxt->stylesheet, NULL); + + g_return_if_fail (ctxt->cur_stmt); +} + +static void +end_font_face (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmts = NULL; + + g_return_if_fail (a_this); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail + (ctxt->cur_stmt + && ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT + && ctxt->stylesheet); + + stmts = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_stmt); + if (!stmts) + goto error; + + ctxt->stylesheet->statements = stmts; + stmts = NULL; + ctxt->cur_stmt = NULL; + + return; + + error: + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + + if (!stmts) { + cr_statement_destroy (stmts); + stmts = NULL; + } +} + +static void +end_document (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + if (!ctxt->stylesheet || ctxt->cur_stmt) + goto error; + + status = cr_doc_handler_set_result (a_this, ctxt->stylesheet); + g_return_if_fail (status == CR_OK); + + ctxt->stylesheet = NULL; + destroy_context (ctxt); + cr_doc_handler_set_ctxt (a_this, NULL); + + return; + + error: + if (ctxt) { + destroy_context (ctxt); + } +} + +static void +charset (CRDocHandler * a_this, CRString * a_charset, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL, + *stmt2 = NULL; + CRString *charset = NULL; + + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + (void) a_location; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->stylesheet); + + charset = cr_string_dup (a_charset) ; + stmt = cr_statement_new_at_charset_rule (ctxt->stylesheet, charset); + if (stmt) + stmt2 = cr_statement_append (ctxt->stylesheet->statements, stmt); + if (!stmt2) { + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + if (charset) { + cr_string_destroy (charset); + } + return; + } + ctxt->stylesheet->statements = stmt2; + stmt2 = NULL; +} + +static void +start_page (CRDocHandler * a_this, + CRString * a_page, + CRString * a_pseudo, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + (void) a_location; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt == NULL); + + ctxt->cur_stmt = cr_statement_new_at_page_rule + (ctxt->stylesheet, NULL, NULL, NULL); + if (a_page) { + ctxt->cur_stmt->kind.page_rule->name = + cr_string_dup (a_page) ; + + if (!ctxt->cur_stmt->kind.page_rule->name) { + goto error; + } + } + if (a_pseudo) { + ctxt->cur_stmt->kind.page_rule->pseudo = + cr_string_dup (a_pseudo) ; + if (!ctxt->cur_stmt->kind.page_rule->pseudo) { + goto error; + } + } + return; + + error: + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } +} + +static void +end_page (CRDocHandler * a_this, + CRString * a_page, + CRString * a_pseudo_page) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmt = NULL; + + (void) a_page; + (void) a_pseudo_page; + + g_return_if_fail (a_this); + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt->cur_stmt + && ctxt->cur_stmt->type == AT_PAGE_RULE_STMT + && ctxt->stylesheet); + + stmt = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_stmt); + + if (stmt) { + ctxt->stylesheet->statements = stmt; + stmt = NULL; + ctxt->cur_stmt = NULL; + } + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + a_page = NULL; /*keep compiler happy */ + a_pseudo_page = NULL; /*keep compiler happy */ +} + +static void +start_media (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + GList *media_list = NULL; + + (void) a_location; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt + && ctxt->cur_stmt == NULL + && ctxt->cur_media_stmt == NULL + && ctxt->stylesheet); + if (a_media_list) { + /*duplicate the media_list */ + media_list = cr_utils_dup_glist_of_cr_string + (a_media_list); + } + ctxt->cur_media_stmt = + cr_statement_new_at_media_rule + (ctxt->stylesheet, NULL, media_list); + +} + +static void +end_media (CRDocHandler * a_this, GList * a_media_list) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmts = NULL; + + (void) a_media_list; + + g_return_if_fail (a_this); + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt + && ctxt->cur_media_stmt + && ctxt->cur_media_stmt->type == AT_MEDIA_RULE_STMT + && ctxt->stylesheet); + + stmts = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_media_stmt); + + if (!stmts) { + cr_statement_destroy (ctxt->cur_media_stmt); + ctxt->cur_media_stmt = NULL; + } + + ctxt->stylesheet->statements = stmts; + stmts = NULL; + + ctxt->cur_stmt = NULL ; + ctxt->cur_media_stmt = NULL ; + a_media_list = NULL; +} + +static void +import_style (CRDocHandler * a_this, + GList * a_media_list, + CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRString *uri = NULL; + CRStatement *stmt = NULL, + *stmt2 = NULL; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + GList *media_list = NULL ; + + (void) a_uri_default_ns; + (void) a_location; + + g_return_if_fail (a_this); + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt->stylesheet); + + uri = cr_string_dup (a_uri) ; + + if (a_media_list) + media_list = cr_utils_dup_glist_of_cr_string (a_media_list) ; + + stmt = cr_statement_new_at_import_rule + (ctxt->stylesheet, uri, media_list, NULL); + + if (!stmt) + goto error; + + if (ctxt->cur_stmt) { + stmt2 = cr_statement_append (ctxt->cur_stmt, stmt); + if (!stmt2) + goto error; + ctxt->cur_stmt = stmt2; + stmt2 = NULL; + stmt = NULL; + } else { + stmt2 = cr_statement_append (ctxt->stylesheet->statements, + stmt); + if (!stmt2) + goto error; + ctxt->stylesheet->statements = stmt2; + stmt2 = NULL; + stmt = NULL; + } + + return; + + error: + if (uri) { + cr_string_destroy (uri); + } + + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + a_uri_default_ns = NULL; /*keep compiler happy */ +} + +static void +start_selector (CRDocHandler * a_this, CRSelector * a_selector_list) +{ + enum CRStatus status = CR_OK ; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + if (ctxt->cur_stmt) { + /*hmm, this should be NULL so free it */ + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + + ctxt->cur_stmt = cr_statement_new_ruleset + (ctxt->stylesheet, a_selector_list, NULL, NULL); +} + +static void +end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + (void) a_selector_list; + + g_return_if_fail (a_this); + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt->cur_stmt && ctxt->stylesheet); + + if (ctxt->cur_stmt) { + CRStatement *stmts = NULL; + + if (ctxt->cur_media_stmt) { + CRAtMediaRule *media_rule = NULL; + + media_rule = ctxt->cur_media_stmt->kind.media_rule; + + stmts = cr_statement_append + (media_rule->rulesets, ctxt->cur_stmt); + + if (!stmts) { + cr_utils_trace_info + ("Could not append a new statement"); + cr_statement_destroy (media_rule->rulesets); + ctxt->cur_media_stmt-> + kind.media_rule->rulesets = NULL; + return; + } + media_rule->rulesets = stmts; + ctxt->cur_stmt = NULL; + } else { + stmts = cr_statement_append + (ctxt->stylesheet->statements, + ctxt->cur_stmt); + if (!stmts) { + cr_utils_trace_info + ("Could not append a new statement"); + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + return; + } + ctxt->stylesheet->statements = stmts; + ctxt->cur_stmt = NULL; + } + + } + + a_selector_list = NULL; /*keep compiler happy */ +} + +static void +property (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, + gboolean a_important) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRDeclaration *decl = NULL, + *decl2 = NULL; + CRString *str = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + /* + *make sure a current ruleset statement has been allocated + *already. + */ + g_return_if_fail + (ctxt->cur_stmt + && + (ctxt->cur_stmt->type == RULESET_STMT + || ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT + || ctxt->cur_stmt->type == AT_PAGE_RULE_STMT)); + + if (a_name) { + str = cr_string_dup (a_name); + g_return_if_fail (str); + } + + /*instantiates a new declaration */ + decl = cr_declaration_new (ctxt->cur_stmt, str, a_expression); + if (decl == NULL) + g_clear_pointer (&str, cr_string_destroy); + g_return_if_fail (decl); + str = NULL; + decl->important = a_important; + /* + *add the new declaration to the current statement + *being build. + */ + switch (ctxt->cur_stmt->type) { + case RULESET_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.ruleset->decl_list, decl); + if (!decl2) { + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.ruleset->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + + case AT_FONT_FACE_RULE_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.font_face_rule->decl_list, + decl); + if (!decl2) { + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.font_face_rule->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + case AT_PAGE_RULE_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.page_rule->decl_list, decl); + if (!decl2) { + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.page_rule->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + + default: + goto error; + break; + } + + return; + + error: + if (str) { + g_free (str); + str = NULL; + } + + if (decl) { + cr_declaration_destroy (decl); + decl = NULL; + } +} + +static void +error (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } +} + +static void +unrecoverable_error (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK); + + if (ctxt) { + if (ctxt->stylesheet) { + status = cr_doc_handler_set_result + (a_this, ctxt->stylesheet); + g_return_if_fail (status == CR_OK); + } + g_free (ctxt); + cr_doc_handler_set_ctxt (a_this, NULL); + } +} + +/******************************************** + *Public methods + ********************************************/ + +/** + * cr_om_parser_new: + *@a_input: the input stream. + * + *Constructor of the CROMParser. + *Returns the newly built instance of #CROMParser. + */ +CROMParser * +cr_om_parser_new (CRInput * a_input) +{ + CROMParser *result = NULL; + enum CRStatus status = CR_OK; + + result = g_try_malloc (sizeof (CROMParser)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CROMParser)); + PRIVATE (result) = g_try_malloc (sizeof (CROMParserPriv)); + + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + goto error; + } + + memset (PRIVATE (result), 0, sizeof (CROMParserPriv)); + + PRIVATE (result)->parser = cr_parser_new_from_input (a_input); + + if (!PRIVATE (result)->parser) { + cr_utils_trace_info ("parsing instantiation failed"); + goto error; + } + + status = cr_om_parser_init_default_sac_handler (result); + + if (status != CR_OK) { + goto error; + } + + return result; + + error: + + if (result) { + cr_om_parser_destroy (result); + } + + return NULL; +} + +/** + * cr_om_parser_parse_buf: + *@a_this: the current instance of #CROMParser. + *@a_buf: the in memory buffer to parse. + *@a_len: the length of the in memory buffer in number of bytes. + *@a_enc: the encoding of the in memory buffer. + *@a_result: out parameter the resulting style sheet + * + *Parses the content of an in memory buffer. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_om_parser_parse_buf (CROMParser * a_this, + const guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, CRStyleSheet ** a_result) +{ + + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_result, CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->parser) { + PRIVATE (a_this)->parser = cr_parser_new (NULL); + } + + status = cr_parser_parse_buf (PRIVATE (a_this)->parser, + a_buf, a_len, a_enc); + + if (status == CR_OK) { + CRStyleSheet *result = NULL; + CRStyleSheet **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + + cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (sac_handler, CR_ERROR); + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + g_return_val_if_fail (status == CR_OK, status); + + if (result) + *a_result = result; + } + + return status; +} + +/** + * cr_om_parser_simply_parse_buf: + *@a_buf: the css2 in memory buffer. + *@a_len: the length of the in memory buffer. + *@a_enc: the encoding of the in memory buffer. + *@a_result: out parameter. The resulting css2 style sheet. + * + *The simpler way to parse an in memory css2 buffer. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_om_parser_simply_parse_buf (const guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet ** a_result) +{ + CROMParser *parser = NULL; + enum CRStatus status = CR_OK; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("Could not create om parser"); + cr_utils_trace_info ("System possibly out of memory"); + return CR_ERROR; + } + + status = cr_om_parser_parse_buf (parser, a_buf, a_len, + a_enc, a_result); + + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + return status; +} + +/** + * cr_om_parser_parse_file: + *@a_this: the current instance of the cssom parser. + *@a_file_uri: the uri of the file. + *(only local file paths are supported so far) + *@a_enc: the encoding of the file. + *@a_result: out parameter. A pointer + *the build css object model. + * + *Parses a css2 stylesheet contained + *in a file. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_om_parser_parse_file (CROMParser * a_this, + const guchar * a_file_uri, + enum CREncoding a_enc, CRStyleSheet ** a_result) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_file_uri && a_result, + CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->parser) { + PRIVATE (a_this)->parser = cr_parser_new_from_file + (a_file_uri, a_enc); + } + + status = cr_parser_parse_file (PRIVATE (a_this)->parser, + a_file_uri, a_enc); + + if (status == CR_OK) { + CRStyleSheet *result = NULL; + CRStyleSheet **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + + cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (sac_handler, CR_ERROR); + resultptr = &result; + status = cr_doc_handler_get_result + (sac_handler, (gpointer *) resultptr); + g_return_val_if_fail (status == CR_OK, status); + if (result) + *a_result = result; + } + + return status; +} + +/** + * cr_om_parser_simply_parse_file: + *@a_file_path: the css2 local file path. + *@a_enc: the file encoding. + *@a_result: out parameter. The returned css stylesheet. + *Must be freed by the caller using cr_stylesheet_destroy. + * + *The simpler method to parse a css2 file. + * + *Returns CR_OK upon successful completion, an error code otherwise. + *Note that this method uses cr_om_parser_parse_file() so both methods + *have the same return values. + */ +enum CRStatus +cr_om_parser_simply_parse_file (const guchar * a_file_path, + enum CREncoding a_enc, + CRStyleSheet ** a_result) +{ + CROMParser *parser = NULL; + enum CRStatus status = CR_OK; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("Could not allocate om parser"); + cr_utils_trace_info ("System may be out of memory"); + return CR_ERROR; + } + + status = cr_om_parser_parse_file (parser, a_file_path, + a_enc, a_result); + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + return status; +} + +/** + * cr_om_parser_parse_paths_to_cascade: + *@a_this: the current instance of #CROMParser + *@a_author_path: the path to the author stylesheet + *@a_user_path: the path to the user stylesheet + *@a_ua_path: the path to the User Agent stylesheet + *@a_encoding: the encoding of the sheets. + *@a_result: out parameter. The resulting cascade if the parsing + *was okay + * + *Parses three sheets located by their paths and build a cascade + * + *Returns CR_OK upon successful completion, an error code otherwise + */ +enum CRStatus +cr_om_parser_parse_paths_to_cascade (CROMParser * a_this, + const guchar * a_author_path, + const guchar * a_user_path, + const guchar * a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) +{ + enum CRStatus status = CR_OK; + + /*0->author sheet, 1->user sheet, 2->UA sheet */ + CRStyleSheet *sheets[3]; + guchar *paths[3]; + CRCascade *result = NULL; + gint i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + memset (sheets, 0, sizeof (CRStyleSheet*) * 3); + paths[0] = (guchar *) a_author_path; + paths[1] = (guchar *) a_user_path; + paths[2] = (guchar *) a_ua_path; + + for (i = 0; i < 3; i++) { + status = cr_om_parser_parse_file (a_this, paths[i], + a_encoding, &sheets[i]); + if (status != CR_OK) { + if (sheets[i]) { + cr_stylesheet_unref (sheets[i]); + sheets[i] = NULL; + } + continue; + } + } + result = cr_cascade_new (sheets[0], sheets[1], sheets[2]); + if (!result) { + for (i = 0; i < 3; i++) { + cr_stylesheet_unref (sheets[i]); + sheets[i] = 0; + } + return CR_ERROR; + } + *a_result = result; + return CR_OK; +} + +/** + * cr_om_parser_simply_parse_paths_to_cascade: + *@a_author_path: the path to the author stylesheet + *@a_user_path: the path to the user stylesheet + *@a_ua_path: the path to the User Agent stylesheet + *@a_encoding: the encoding of the sheets. + *@a_result: out parameter. The resulting cascade if the parsing + *was okay + * + *Parses three sheets located by their paths and build a cascade + * + *Returns CR_OK upon successful completion, an error code otherwise + */ +enum CRStatus +cr_om_parser_simply_parse_paths_to_cascade (const guchar * a_author_path, + const guchar * a_user_path, + const guchar * a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("could not allocated om parser"); + cr_utils_trace_info ("System may be out of memory"); + return CR_ERROR; + } + status = cr_om_parser_parse_paths_to_cascade (parser, + a_author_path, + a_user_path, + a_ua_path, + a_encoding, a_result); + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + return status; +} + +/** + * cr_om_parser_destroy: + *@a_this: the current instance of #CROMParser. + * + *Destructor of the #CROMParser. + */ +void +cr_om_parser_destroy (CROMParser * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->parser) { + cr_parser_destroy (PRIVATE (a_this)->parser); + PRIVATE (a_this)->parser = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + if (a_this) { + g_free (a_this); + a_this = NULL; + } +} diff --git a/src/3rdparty/libcroco/src/cr-om-parser.h b/src/3rdparty/libcroco/src/cr-om-parser.h new file mode 100644 index 0000000..13d35b1 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-om-parser.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +#ifndef __CR_OM_PARSER_H__ +#define __CR_OM_PARSER_H__ + +#include "cr-parser.h" +#include "cr-cascade.h" + + +/** + *@file + *The definition of the CSS Object Model Parser. + *This parser uses (and sits) the SAC api of libcroco defined + *in cr-parser.h and cr-doc-handler.h + */ + +G_BEGIN_DECLS + +typedef struct _CROMParser CROMParser ; +typedef struct _CROMParserPriv CROMParserPriv ; + +/** + *The Object model parser. + *Can parse a css file and build a css object model. + *This parser uses an instance of #CRParser and defines + *a set of SAC callbacks to build the Object Model. + */ +struct _CROMParser +{ + CROMParserPriv *priv ; +} ; + +CROMParser * cr_om_parser_new (CRInput *a_input) ; + + +enum CRStatus cr_om_parser_simply_parse_file (const guchar *a_file_path, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_file (CROMParser *a_this, + const guchar *a_file_uri, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_simply_parse_buf (const guchar *a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_buf (CROMParser *a_this, + const guchar *a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_paths_to_cascade (CROMParser *a_this, + const guchar *a_author_path, + const guchar *a_user_path, + const guchar *a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) ; + +enum CRStatus cr_om_parser_simply_parse_paths_to_cascade (const guchar *a_author_path, + const guchar *a_user_path, + const guchar *a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) ; + +void cr_om_parser_destroy (CROMParser *a_this) ; + +G_END_DECLS + +#endif /*__CR_OM_PARSER_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-parser.c b/src/3rdparty/libcroco/src/cr-parser.c new file mode 100644 index 0000000..e9a5f90 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-parser.c @@ -0,0 +1,4568 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +/** + *@CRParser: + * + *The definition of the #CRParser class. + */ + +#include "string.h" +#include "cr-parser.h" +#include "cr-num.h" +#include "cr-term.h" +#include "cr-simple-sel.h" +#include "cr-attr-sel.h" + +/* + *Random notes: + *CSS core syntax vs CSS level 2 syntax + *===================================== + * + *One must keep in mind + *that css UA must comply with two syntaxes. + * + *1/the specific syntax that defines the css language + *for a given level of specification (e.g css2 syntax + *defined in appendix D.1 of the css2 spec) + * + *2/the core (general) syntax that is there to allow + *UAs to parse style sheets written in levels of CSS that + *didn't exist at the time the UAs were created. + * + *the name of parsing functions (or methods) contained in this file + *follows the following scheme: cr_parser_parse_<production_name> (...) ; + *where <production_name> is the name + *of a production of the css2 language. + *When a given production is + *defined by the css2 level grammar *and* by the + *css core syntax, there will be two functions to parse that production: + *one will parse the production defined by the css2 level grammar and the + *other will parse the production defined by the css core grammar. + *The css2 level grammar related parsing function will be called: + *cr_parser_parse_<production_name> (...) ; + *Then css core grammar related parsing function will be called: + *cr_parser_parse_<production_name>_core (...) ; + * + *If a production is defined only by the css core grammar, then + *it will be named: + *cr_parser_parse_<production_name>_core (...) ; + */ + +typedef struct _CRParserError CRParserError; + +/** + *An abstraction of an error reported by by the + *parsing routines. + */ +struct _CRParserError { + guchar *msg; + enum CRStatus status; + glong line; + glong column; + glong byte_num; +}; + +enum CRParserState { + READY_STATE = 0, + TRY_PARSE_CHARSET_STATE, + CHARSET_PARSED_STATE, + TRY_PARSE_IMPORT_STATE, + IMPORT_PARSED_STATE, + TRY_PARSE_RULESET_STATE, + RULESET_PARSED_STATE, + TRY_PARSE_MEDIA_STATE, + MEDIA_PARSED_STATE, + TRY_PARSE_PAGE_STATE, + PAGE_PARSED_STATE, + TRY_PARSE_FONT_FACE_STATE, + FONT_FACE_PARSED_STATE +} ; + +/** + *The private attributes of + *#CRParser. + */ +struct _CRParserPriv { + /** + *The tokenizer + */ + CRTknzr *tknzr; + + /** + *The sac handlers to call + *to notify the parsing of + *the css2 constructions. + */ + CRDocHandler *sac_handler; + + /** + *A stack of errors reported + *by the parsing routines. + *Contains instance of #CRParserError. + *This pointer is the top of the stack. + */ + GList *err_stack; + + enum CRParserState state; + gboolean resolve_import; + gboolean is_case_sensitive; + gboolean use_core_grammar; +}; + +#define PRIVATE(obj) ((obj)->priv) + +#define CHARS_TAB_SIZE 12 + +#define RECURSIVE_CALLERS_LIMIT 100 + +/** + * IS_NUM: + *@a_char: the char to test. + *return TRUE if the character is a number ([0-9]), FALSE otherwise + */ +#define IS_NUM(a_char) (((a_char) >= '0' && (a_char) <= '9')?TRUE:FALSE) + +/** + *Checks if 'status' equals CR_OK. If not, goto the 'error' label. + * + *@param status the status (of type enum CRStatus) to test. + *@param is_exception if set to FALSE, the final status returned + *by the current function will be CR_PARSING_ERROR. If set to TRUE, the + *current status will be the current value of the 'status' variable. + * + */ +#define CHECK_PARSING_STATUS(status, is_exception) \ +if ((status) != CR_OK) \ +{ \ + if (is_exception == FALSE) \ + { \ + status = CR_PARSING_ERROR ; \ + } \ + goto error ; \ +} + +/** + * CHECK_PARSING_STATUS_ERR: + *@a_this: the current instance of #CRParser . + *@a_status: the status to check. Is of type enum #CRStatus. + *@a_is_exception: in case of error, if is TRUE, the status + *is set to CR_PARSING_ERROR before goto error. If is false, the + *real low level status is kept and will be returned by the + *upper level function that called this macro. Usually, this must + *be set to FALSE. + * + *same as CHECK_PARSING_STATUS() but this one pushes an error + *on the parser error stack when an error arises. + * + */ +#define CHECK_PARSING_STATUS_ERR(a_this, a_status, a_is_exception,\ + a_err_msg, a_err_status) \ +if ((a_status) != CR_OK) \ +{ \ + if (a_is_exception == FALSE) a_status = CR_PARSING_ERROR ; \ + cr_parser_push_error (a_this, a_err_msg, a_err_status) ; \ + goto error ; \ +} + +/** + *Peeks the next char from the input stream of the current parser + *by invoking cr_tknzr_input_peek_char(). + *invokes CHECK_PARSING_STATUS on the status returned by + *cr_tknzr_peek_char(). + * + *@param a_this the current instance of #CRParser. + *@param a_to_char a pointer to the char where to store the + *char peeked. + */ +#define PEEK_NEXT_CHAR(a_this, a_to_char) \ +{\ +status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) \ +} + +/** + *Reads the next char from the input stream of the current parser. + *In case of error, jumps to the "error:" label located in the + *function where this macro is called. + *@param a_this the current instance of #CRParser + *@param to_char a pointer to the guint32 char where to store + *the character read. + */ +#define READ_NEXT_CHAR(a_this, a_to_char) \ +status = cr_tknzr_read_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Gets information about the current position in + *the input of the parser. + *In case of failure, this macro returns from the + *calling function and + *returns a status code of type enum #CRStatus. + *@param a_this the current instance of #CRParser. + *@param a_pos out parameter. A pointer to the position + *inside the current parser input. Must + */ +#define RECORD_INITIAL_POS(a_this, a_pos) \ +status = cr_tknzr_get_cur_pos (PRIVATE \ +(a_this)->tknzr, a_pos) ; \ +g_return_val_if_fail (status == CR_OK, status) + +/** + *Gets the address of the current byte inside the + *parser input. + *@param parser the current instance of #CRParser. + *@param addr out parameter a pointer (guchar*) + *to where the address must be put. + */ +#define RECORD_CUR_BYTE_ADDR(a_this, a_addr) \ +status = cr_tknzr_get_cur_byte_addr \ + (PRIVATE (a_this)->tknzr, a_addr) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Peeks a byte from the topmost parser input at + *a given offset from the current position. + *If it fails, goto the "error:" label. + * + *@param a_parser the current instance of #CRParser. + *@param a_offset the offset of the byte to peek, the + *current byte having the offset '0'. + *@param a_byte_ptr out parameter a pointer (guchar*) to + *where the peeked char is to be stored. + */ +#define PEEK_BYTE(a_parser, a_offset, a_byte_ptr) \ +status = cr_tknzr_peek_byte (PRIVATE (a_this)->tknzr, \ + a_offset, \ + a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +#define BYTE(a_parser, a_offset, a_eof) \ +cr_tknzr_peek_byte2 (PRIVATE (a_this)->tknzr, a_offset, a_eof) + +/** + *Reads a byte from the topmost parser input + *steam. + *If it fails, goto the "error" label. + *@param a_this the current instance of #CRParser. + *@param a_byte_ptr the guchar * where to put the read char. + */ +#define READ_NEXT_BYTE(a_this, a_byte_ptr) \ +status = cr_tknzr_read_byte (PRIVATE (a_this)->tknzr, a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skips a given number of byte in the topmost + *parser input. Don't update line and column number. + *In case of error, jumps to the "error:" label + *of the surrounding function. + *@param a_parser the current instance of #CRParser. + *@param a_nb_bytes the number of bytes to skip. + */ +#define SKIP_BYTES(a_this, a_nb_bytes) \ +status = cr_tknzr_seek_index (PRIVATE (a_this)->tknzr, \ + CR_SEEK_CUR, a_nb_bytes) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skip utf8 encoded characters. + *Updates line and column numbers. + *@param a_parser the current instance of #CRParser. + *@param a_nb_chars the number of chars to skip. Must be of + *type glong. + */ +#define SKIP_CHARS(a_parser, a_nb_chars) \ +{ \ +glong nb_chars = a_nb_chars ; \ +status = cr_tknzr_consume_chars \ + (PRIVATE (a_parser)->tknzr,0, &nb_chars) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; \ +} + +/** + *Tests the condition and if it is false, sets + *status to "CR_PARSING_ERROR" and goto the 'error' + *label. + *@param condition the condition to test. + */ +#define ENSURE_PARSING_COND(condition) \ +if (! (condition)) {status = CR_PARSING_ERROR; goto error ;} + +#define ENSURE_PARSING_COND_ERR(a_this, a_condition, \ + a_err_msg, a_err_status) \ +if (! (a_condition)) \ +{ \ + status = CR_PARSING_ERROR; \ + cr_parser_push_error (a_this, a_err_msg, a_err_status) ; \ + goto error ; \ +} + +#define GET_NEXT_TOKEN(a_this, a_token_ptr) \ +status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, \ + a_token_ptr) ; \ +ENSURE_PARSING_COND (status == CR_OK) ; + +#ifdef WITH_UNICODE_ESCAPE_AND_RANGE +static enum CRStatus cr_parser_parse_unicode_escape (CRParser * a_this, + guint32 * a_unicode); +static enum CRStatus cr_parser_parse_escape (CRParser * a_this, + guint32 * a_esc_code); + +static enum CRStatus cr_parser_parse_unicode_range (CRParser * a_this, + CRString ** a_inf, + CRString ** a_sup); +#endif + +static enum CRStatus cr_parser_parse_stylesheet_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_atrule_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_ruleset_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_selector_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_declaration_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_any_core (CRParser * a_this, + guint n_calls); + +static enum CRStatus cr_parser_parse_block_core (CRParser * a_this, + guint n_calls); + +static enum CRStatus cr_parser_parse_value_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_string (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_ident (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_uri (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_function (CRParser * a_this, + CRString ** a_func_name, + CRTerm ** a_expr); +static enum CRStatus cr_parser_parse_property (CRParser * a_this, + CRString ** a_property); + +static enum CRStatus cr_parser_parse_attribute_selector (CRParser * a_this, + CRAttrSel ** a_sel); + +static enum CRStatus cr_parser_parse_simple_selector (CRParser * a_this, + CRSimpleSel ** a_sel); + +static enum CRStatus cr_parser_parse_simple_sels (CRParser * a_this, + CRSimpleSel ** a_sel); + +static CRParserError *cr_parser_error_new (const guchar * a_msg, + enum CRStatus); + +static void cr_parser_error_set_msg (CRParserError * a_this, + const guchar * a_msg); + +static void cr_parser_error_dump (CRParserError * a_this); + +static void cr_parser_error_set_status (CRParserError * a_this, + enum CRStatus a_status); + +static void cr_parser_error_set_pos (CRParserError * a_this, + glong a_line, + glong a_column, glong a_byte_num); +static void + cr_parser_error_destroy (CRParserError * a_this); + +static enum CRStatus cr_parser_push_error (CRParser * a_this, + const guchar * a_msg, + enum CRStatus a_status); + +static enum CRStatus cr_parser_dump_err_stack (CRParser * a_this, + gboolean a_clear_errs); +static enum CRStatus + cr_parser_clear_errors (CRParser * a_this); + +/***************************** + *error managemet methods + *****************************/ + +/** + *Constructor of #CRParserError class. + *@param a_msg the brute error message. + *@param a_status the error status. + *@return the newly built instance of #CRParserError. + */ +static CRParserError * +cr_parser_error_new (const guchar * a_msg, enum CRStatus a_status) +{ + CRParserError *result = NULL; + + result = g_try_malloc (sizeof (CRParserError)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRParserError)); + + cr_parser_error_set_msg (result, a_msg); + cr_parser_error_set_status (result, a_status); + + return result; +} + +/** + *Sets the message associated to this instance of #CRError. + *@param a_this the current instance of #CRParserError. + *@param a_msg the new message. + */ +static void +cr_parser_error_set_msg (CRParserError * a_this, const guchar * a_msg) +{ + g_return_if_fail (a_this); + + if (a_this->msg) { + g_free (a_this->msg); + } + + a_this->msg = (guchar *) g_strdup ((const gchar *) a_msg); +} + +/** + *Sets the error status. + *@param a_this the current instance of #CRParserError. + *@param a_status the new error status. + * + */ +static void +cr_parser_error_set_status (CRParserError * a_this, enum CRStatus a_status) +{ + g_return_if_fail (a_this); + + a_this->status = a_status; +} + +/** + *Sets the position of the parser error. + *@param a_this the current instance of #CRParserError. + *@param a_line the line number. + *@param a_column the column number. + *@param a_byte_num the byte number. + */ +static void +cr_parser_error_set_pos (CRParserError * a_this, + glong a_line, glong a_column, glong a_byte_num) +{ + g_return_if_fail (a_this); + + a_this->line = a_line; + a_this->column = a_column; + a_this->byte_num = a_byte_num; +} + +static void +cr_parser_error_dump (CRParserError * a_this) +{ + g_return_if_fail (a_this); + + g_printerr ("parsing error: %ld:%ld:", a_this->line, a_this->column); + + g_printerr ("%s\n", a_this->msg); +} + +/** + *The destructor of #CRParserError. + *@param a_this the current instance of #CRParserError. + */ +static void +cr_parser_error_destroy (CRParserError * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->msg) { + g_free (a_this->msg); + a_this->msg = NULL; + } + + g_free (a_this); +} + +/** + *Pushes an error on the parser error stack. + *@param a_this the current instance of #CRParser. + *@param a_msg the error message. + *@param a_status the error status. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_push_error (CRParser * a_this, + const guchar * a_msg, enum CRStatus a_status) +{ + enum CRStatus status = CR_OK; + + CRParserError *error = NULL; + CRInputPos pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_msg, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &pos); + + error = cr_parser_error_new (a_msg, a_status); + + g_return_val_if_fail (error, CR_ERROR); + + cr_parser_error_set_pos + (error, pos.line, pos.col, pos.next_byte_index - 1); + + PRIVATE (a_this)->err_stack = + g_list_prepend (PRIVATE (a_this)->err_stack, error); + + if (PRIVATE (a_this)->err_stack == NULL) + goto error; + + return CR_OK; + + error: + + if (error) { + cr_parser_error_destroy (error); + error = NULL; + } + + return status; +} + +/** + *Dumps the error stack using g_printerr. + *@param a_this the current instance of #CRParser. + *@param a_clear_errs whether to clear the error stack + *after the dump or not. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_dump_err_stack (CRParser * a_this, gboolean a_clear_errs) +{ + GList *cur = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->err_stack == NULL) + return CR_OK; + + for (cur = PRIVATE (a_this)->err_stack; cur; cur = cur->next) { + cr_parser_error_dump ((CRParserError *) cur->data); + } + + if (a_clear_errs == TRUE) { + cr_parser_clear_errors (a_this); + } + + return CR_OK; +} + +/** + *Clears all the errors contained in the parser error stack. + *Frees all the errors, and the stack that contains'em. + *@param a_this the current instance of #CRParser. + */ +static enum CRStatus +cr_parser_clear_errors (CRParser * a_this) +{ + GList *cur = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (cur = PRIVATE (a_this)->err_stack; cur; cur = cur->next) { + if (cur->data) { + cr_parser_error_destroy ((CRParserError *) + cur->data); + } + } + + if (PRIVATE (a_this)->err_stack) { + g_list_free (PRIVATE (a_this)->err_stack); + PRIVATE (a_this)->err_stack = NULL; + } + + return CR_OK; +} + +/** + * cr_parser_try_to_skip_spaces_and_comments: + *@a_this: the current instance of #CRParser. + * + *Same as cr_parser_try_to_skip_spaces() but this one skips + *spaces and comments. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_try_to_skip_spaces_and_comments (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK) + goto error; + } + while ((token != NULL) + && (token->type == COMMENT_TK || token->type == S_TK)); + + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + + return status; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + return status; +} + +/*************************************** + *End of Parser input handling routines + ***************************************/ + + +/************************************* + *Non trivial terminal productions + *parsing routines + *************************************/ + +/** + *Parses a css stylesheet following the core css grammar. + *This is mainly done for test purposes. + *During the parsing, no callback is called. This is just + *to validate that the stylesheet is well formed according to the + *css core syntax. + *stylesheet : [ CDO | CDC | S | statement ]*; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_stylesheet_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + continue_parsing: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto done; + } else if (status != CR_OK) { + goto error; + } + + switch (token->type) { + + case CDO_TK: + case CDC_TK: + goto continue_parsing; + break; + default: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_statement_core (a_this); + cr_parser_clear_errors (a_this); + if (status == CR_OK) { + goto continue_parsing; + } else if (status == CR_END_OF_INPUT_ERROR) { + goto done; + } else { + goto error; + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + cr_parser_push_error + (a_this, (const guchar *) "could not recognize next production", CR_ERROR); + + cr_parser_dump_err_stack (a_this, TRUE); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an at-rule as defined by the css core grammar + *in chapter 4.1 in the css2 spec. + *at-rule : ATKEYWORD S* any* [ block | ';' S* ]; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_atrule_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && + (token->type == ATKEYWORD_TK + || token->type == IMPORT_SYM_TK + || token->type == PAGE_SYM_TK + || token->type == MEDIA_SYM_TK + || token->type == FONT_FACE_SYM_TK + || token->type == CHARSET_SYM_TK)); + + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + do { + status = cr_parser_parse_any_core (a_this, 0); + } while (status == CR_OK); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == CBO_TK) { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_block_core (a_this, 0); + CHECK_PARSING_STATUS (status, + FALSE); + goto done; + } else if (token->type == SEMICOLON_TK) { + goto done; + } else { + status = CR_PARSING_ERROR ; + goto error; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, + &init_pos); + return status; +} + +/** + *Parses a ruleset as defined by the css core grammar in chapter + *4.1 of the css2 spec. + *ruleset ::= selector? '{' S* declaration? [ ';' S* declaration? ]* '}' S*; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_ruleset_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_selector_core (a_this); + + ENSURE_PARSING_COND (status == CR_OK + || status == CR_PARSING_ERROR + || status == CR_END_OF_INPUT_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration_core (a_this); + + parse_declaration_list: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + if (token->type == CBC_TK) { + goto done; + } + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == SEMICOLON_TK); + + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration_core (a_this); + cr_parser_clear_errors (a_this); + ENSURE_PARSING_COND (status == CR_OK || status == CR_PARSING_ERROR); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + if (token->type == CBC_TK) { + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto done; + } else { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + goto parse_declaration_list; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK) { + return CR_OK; + } + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "selector" as specified by the css core + *grammar. + *selector : any+; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_selector_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_any_core (a_this, 0); + CHECK_PARSING_STATUS (status, FALSE); + + do { + status = cr_parser_parse_any_core (a_this, 0); + + } while (status == CR_OK); + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "block" as defined in the css core grammar + *in chapter 4.1 of the css2 spec. + *block ::= '{' S* [ any | block | ATKEYWORD S* | ';' ]* '}' S*; + *@param a_this the current instance of #CRParser. + *@param n_calls used to limit recursion depth + *FIXME: code this function. + */ +static enum CRStatus +cr_parser_parse_block_core (CRParser * a_this, + guint n_calls) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (n_calls > RECURSIVE_CALLERS_LIMIT) + return CR_ERROR; + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + + parse_block_content: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == CBC_TK) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto done; + } else if (token->type == SEMICOLON_TK) { + goto parse_block_content; + } else if (token->type == ATKEYWORD_TK) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto parse_block_content; + } else if (token->type == CBO_TK) { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_block_core (a_this, n_calls + 1); + CHECK_PARSING_STATUS (status, FALSE); + goto parse_block_content; + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_any_core (a_this, n_calls + 1); + CHECK_PARSING_STATUS (status, FALSE); + goto parse_block_content; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK) + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +static enum CRStatus +cr_parser_parse_declaration_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + CRString *prop = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_property (a_this, &prop); + CHECK_PARSING_STATUS (status, FALSE); + cr_parser_clear_errors (a_this); + ENSURE_PARSING_COND (status == CR_OK && prop); + cr_string_destroy (prop); + prop = NULL; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == DELIM_TK + && token->u.unichar == ':'); + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_value_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + + return CR_OK; + + error: + + if (prop) { + cr_string_destroy (prop); + prop = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "value" production as defined by the css core grammar + *in chapter 4.1. + *value ::= [ any | block | ATKEYWORD S* ]+; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_value_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + glong ref = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + RECORD_INITIAL_POS (a_this, &init_pos); + + continue_parsing: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + switch (token->type) { + case CBO_TK: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_block_core (a_this, 0); + CHECK_PARSING_STATUS (status, FALSE); + ref++; + goto continue_parsing; + + case ATKEYWORD_TK: + cr_parser_try_to_skip_spaces_and_comments (a_this); + ref++; + goto continue_parsing; + + default: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_any_core (a_this, 0); + if (status == CR_OK) { + ref++; + goto continue_parsing; + } else if (status == CR_PARSING_ERROR) { + status = CR_OK; + goto done; + } else { + goto error; + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK && ref) + return CR_OK; + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an "any" as defined by the css core grammar in the + *css2 spec in chapter 4.1. + *any ::= [ IDENT | NUMBER | PERCENTAGE | DIMENSION | STRING + * | DELIM | URI | HASH | UNICODE-RANGE | INCLUDES + * | FUNCTION | DASHMATCH | '(' any* ')' | '[' any* ']' ] S*; + * + *@param a_this the current instance of #CRParser. + *@param n_calls used to limit recursion depth + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_any_core (CRParser * a_this, + guint n_calls) +{ + CRToken *token1 = NULL, + *token2 = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + if (n_calls > RECURSIVE_CALLERS_LIMIT) + return CR_ERROR; + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token1); + + ENSURE_PARSING_COND (status == CR_OK && token1); + + switch (token1->type) { + case IDENT_TK: + case NUMBER_TK: + case RGB_TK: + case PERCENTAGE_TK: + case DIMEN_TK: + case EMS_TK: + case EXS_TK: + case LENGTH_TK: + case ANGLE_TK: + case FREQ_TK: + case TIME_TK: + case STRING_TK: + case DELIM_TK: + case URI_TK: + case HASH_TK: + case UNICODERANGE_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case S_TK: + case COMMENT_TK: + case IMPORTANT_SYM_TK: + status = CR_OK; + break; + case FUNCTION_TK: + /* + *this case isn't specified by the spec but it + *does happen. So we have to handle it. + *We must consider function with parameters. + *We consider parameter as being an "any*" production. + */ + do { + status = cr_parser_parse_any_core (a_this, n_calls + 1); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == PC_TK); + break; + case PO_TK: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK && token2); + + if (token2->type == PC_TK) { + cr_token_destroy (token2); + token2 = NULL; + goto done; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token2); + token2 = NULL; + } + + do { + status = cr_parser_parse_any_core (a_this, n_calls + 1); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == PC_TK); + status = CR_OK; + break; + + case BO_TK: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK && token2); + + if (token2->type == BC_TK) { + cr_token_destroy (token2); + token2 = NULL; + goto done; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token2); + token2 = NULL; + } + + do { + status = cr_parser_parse_any_core (a_this, n_calls + 1); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == BC_TK); + status = CR_OK; + break; + default: + status = CR_PARSING_ERROR; + goto error; + } + + done: + if (token1) { + cr_token_destroy (token1); + token1 = NULL; + } + + if (token2) { + cr_token_destroy (token2); + token2 = NULL; + } + + return CR_OK; + + error: + + if (token1) { + cr_token_destroy (token1); + token1 = NULL; + } + + if (token2) { + cr_token_destroy (token2); + token2 = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + *Parses an attribute selector as defined in the css2 spec in + *appendix D.1: + *attrib ::= '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* + * [ IDENT | STRING ] S* ]? ']' + * + *@param a_this the "this pointer" of the current instance of + *#CRParser . + *@param a_sel out parameter. The successfully parsed attribute selector. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_attribute_selector (CRParser * a_this, + CRAttrSel ** a_sel) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRAttrSel *result = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && a_sel, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == BO_TK); + cr_parsing_location_copy + (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + result = cr_attr_sel_new (); + if (!result) { + cr_utils_trace_info ("result failed") ; + status = CR_OUT_OF_MEMORY_ERROR ; + goto error ; + } + cr_parsing_location_copy (&result->location, + &location) ; + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IDENT_TK); + + result->name = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == INCLUDES_TK) { + result->match_way = INCLUDES; + goto parse_right_part; + } else if (token->type == DASHMATCH_TK) { + result->match_way = DASHMATCH; + goto parse_right_part; + } else if (token->type == DELIM_TK && token->u.unichar == '=') { + result->match_way = EQUALS; + goto parse_right_part; + } else if (token->type == BC_TK) { + result->match_way = SET; + goto done; + } + + parse_right_part: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == IDENT_TK) { + result->value = token->u.str; + token->u.str = NULL; + } else if (token->type == STRING_TK) { + result->value = token->u.str; + token->u.str = NULL; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == BC_TK); + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (*a_sel) { + status = cr_attr_sel_append_attr_sel (*a_sel, result); + CHECK_PARSING_STATUS (status, FALSE); + } else { + *a_sel = result; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (result) { + cr_attr_sel_destroy (result); + result = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "property" as specified by the css2 spec at [4.1.1]: + *property : IDENT S*; + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param GString a_property out parameter. The parsed property without the + *trailing spaces. If *a_property is NULL, this function allocates a + *new instance of GString and set it content to the parsed property. + *If not, the property is just appended to a_property's previous content. + *In both cases, it is up to the caller to free a_property. + *@return CR_OK upon successful completion, CR_PARSING_ERROR if the + *next construction was not a "property", or an error code. + */ +static enum CRStatus +cr_parser_parse_property (CRParser * a_this, + CRString ** a_property) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_property, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_ident (a_this, a_property); + CHECK_PARSING_STATUS (status, TRUE); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_term: + *@a_term: out parameter. The successfully parsed term. + * + *Parses a "term" as defined in the css2 spec, appendix D.1: + *term ::= unary_operator? [NUMBER S* | PERCENTAGE S* | LENGTH S* | + *EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* | function ] | + *STRING S* | IDENT S* | URI S* | RGB S* | UNICODERANGE S* | hexcolor + * + * As a special case for 'an+b', parse integer followed immediately by 'n'. + * The 'an' is parsed as a DIMEN. + * + *TODO: handle parsing of 'RGB' + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_term (CRParser * a_this, CRTerm ** a_term) +{ + enum CRStatus status = CR_PARSING_ERROR; + CRInputPos init_pos; + CRTerm *result = NULL; + CRTerm *param = NULL; + CRToken *token = NULL; + CRString *func_name = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && a_term, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + result = cr_term_new (); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + + cr_parsing_location_copy (&location, &token->location) ; + if (token->type == DELIM_TK && token->u.unichar == '+') { + result->unary_op = PLUS_UOP; + cr_token_destroy (token) ; + token = NULL ; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + } else if (token->type == DELIM_TK && token->u.unichar == '-') { + result->unary_op = MINUS_UOP; + cr_token_destroy (token) ; + token = NULL ; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + } + + if (token->type == EMS_TK + || token->type == EXS_TK + || token->type == LENGTH_TK + || token->type == ANGLE_TK + || token->type == TIME_TK + || token->type == FREQ_TK + || token->type == PERCENTAGE_TK + || token->type == NUMBER_TK) { + status = cr_term_set_number (result, token->u.num); + CHECK_PARSING_STATUS (status, TRUE); + token->u.num = NULL; + status = CR_OK; + } else if (token && token->type == FUNCTION_TK) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_function (a_this, &func_name, + ¶m); + + if (status == CR_OK) { + status = cr_term_set_function (result, + func_name, + param); + CHECK_PARSING_STATUS (status, TRUE); + } + } else if (token && token->type == STRING_TK) { + status = cr_term_set_string (result, + token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == IDENT_TK) { + status = cr_term_set_ident (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == URI_TK) { + status = cr_term_set_uri (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == RGB_TK) { + status = cr_term_set_rgb (result, token->u.rgb); + CHECK_PARSING_STATUS (status, TRUE); + token->u.rgb = NULL; + } else if (token && token->type == UNICODERANGE_TK) { + result->type = TERM_UNICODERANGE; + status = CR_PARSING_ERROR; + } else if (token && token->type == HASH_TK) { + status = cr_term_set_hash (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == DIMEN_TK) { + gboolean n = !strcmp(token->dimen->stryng->str, "n"); + status = cr_term_set_number (result, token->u.num); + result->n = n; // For nth-child (an+b) + CHECK_PARSING_STATUS (status, TRUE); + token->u.num = NULL; + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + } + + if (status != CR_OK) { + goto error; + } + cr_parsing_location_copy (&result->location, + &location) ; + *a_term = cr_term_append_term (*a_term, result); + + result = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (result) { + cr_term_destroy (result); + result = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (param) { + cr_term_destroy (param); + param = NULL; + } + + if (func_name) { + cr_string_destroy (func_name); + func_name = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_simple_selector: + *@a_this: the "this pointer" of the current instance of #CRParser. + *@a_sel: out parameter. Is set to the successfully parsed simple + *selector. + * + *Parses a "simple_selector" as defined by the css2 spec in appendix D.1 : + *element_name? [ HASH | class | attrib | pseudo ]* S* + *and where pseudo is: + *pseudo ::= ':' [ IDENT | FUNCTION S* IDENT S* ')' ] + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_simple_selector (CRParser * a_this, CRSimpleSel ** a_sel) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRToken *token = NULL; + CRSimpleSel *sel = NULL; + CRPseudo *pseudo = NULL; + CRAdditionalSel *add_sel_list = NULL; + gboolean found_sel = FALSE; + + g_return_val_if_fail (a_this && a_sel, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + sel = cr_simple_sel_new (); + ENSURE_PARSING_COND (sel); + + cr_parsing_location_copy + (&sel->location, + &token->location) ; + + if (token && token->type == DELIM_TK + && token->u.unichar == '*') { + int comb = (int)sel->type_mask | (int) UNIVERSAL_SELECTOR; + sel->type_mask = (enum SimpleSelectorType)comb; + sel->name = cr_string_new_from_string ("*"); + found_sel = TRUE; + } else if (token && token->type == IDENT_TK) { + int comb = (int)sel->type_mask | (int) TYPE_SELECTOR; + sel->type_mask = (enum SimpleSelectorType)comb; + sel->name = token->u.str; + token->u.str = NULL; + found_sel = TRUE; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, + token); + token = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + while (cr_tknzr_get_nb_bytes_left ((PRIVATE (a_this)->tknzr))) { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK) + goto error; + + if (token && token->type == HASH_TK) { + /*we parsed an attribute id */ + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (ID_ADD_SELECTOR); + + add_sel->content.id_name = token->u.str; + token->u.str = NULL; + + cr_parsing_location_copy + (&add_sel->location, + &token->location) ; + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + } else if (token && (token->type == DELIM_TK) + && (token->u.unichar == '.')) { + cr_token_destroy (token); + token = NULL; + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + if (token && token->type == IDENT_TK) { + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (CLASS_ADD_SELECTOR); + + add_sel->content.class_name = token->u.str; + token->u.str = NULL; + + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + + cr_parsing_location_copy + (&add_sel->location, + & token->location) ; + } else { + status = CR_PARSING_ERROR; + goto error; + } + } else if (token && token->type == BO_TK) { + CRAttrSel *attr_sel = NULL; + CRAdditionalSel *add_sel = NULL; + + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + if (status != CR_OK) + goto error; + token = NULL; + + status = cr_parser_parse_attribute_selector + (a_this, &attr_sel); + CHECK_PARSING_STATUS (status, FALSE); + + add_sel = cr_additional_sel_new_with_type + (ATTRIBUTE_ADD_SELECTOR); + + ENSURE_PARSING_COND (add_sel != NULL); + + add_sel->content.attr_sel = attr_sel; + + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + cr_parsing_location_copy + (&add_sel->location, + &attr_sel->location) ; + } else if (token && (token->type == DELIM_TK) + && (token->u.unichar == ':')) { + + /*try to parse a pseudo */ + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + pseudo = cr_pseudo_new (); + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + cr_parsing_location_copy + (&pseudo->location, + &token->location) ; + + /* Save selector name for use by 'type' pseudo selectors */ + if (sel->name) + pseudo->sel_name = cr_string_dup (sel->name); + + if (token->type == IDENT_TK) { + pseudo->type = IDENT_PSEUDO; + pseudo->name = token->u.str; + token->u.str = NULL; + found_sel = TRUE; + } else if (token->type == FUNCTION_TK) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_function (a_this, &pseudo->name, &pseudo->term); + ENSURE_PARSING_COND (status == CR_OK); + + pseudo->type = FUNCTION_PSEUDO; + found_sel = TRUE; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + if (status == CR_OK) { + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (PSEUDO_CLASS_ADD_SELECTOR); + + add_sel->content.pseudo = pseudo; + cr_parsing_location_copy + (&add_sel->location, + &pseudo->location) ; + pseudo = NULL; + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + status = CR_OK; + } + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + break; + } + } // for loop + + if (status == CR_OK && found_sel == TRUE) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + + sel->add_sel = add_sel_list; + add_sel_list = NULL; + + if (*a_sel == NULL) { + *a_sel = sel; + } else { + cr_simple_sel_append_simple_sel (*a_sel, sel); + } + + sel = NULL; + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + } else { + status = CR_PARSING_ERROR; + } + + error: + + g_clear_pointer (&pseudo, cr_pseudo_destroy); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (add_sel_list) { + cr_additional_sel_destroy (add_sel_list); + add_sel_list = NULL; + } + + if (sel) { + cr_simple_sel_destroy (sel); + sel = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; + +} + +/** + * cr_parser_parse_simple_sels: + *@a_this: the this pointer of the current instance of #CRParser. + *@a_start: a pointer to the + *first chararcter of the successfully parsed + *string. + *@a_end: a pointer to the last character of the successfully parsed + *string. + * + *Parses a "selector" as defined by the css2 spec in appendix D.1: + *selector ::= simple_selector [ combinator simple_selector ]* + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_simple_sels (CRParser * a_this, + CRSimpleSel ** a_sel) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRSimpleSel *sel = NULL; + guint32 cur_char = 0; + + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_sel, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_simple_selector (a_this, &sel); + CHECK_PARSING_STATUS (status, FALSE); + + *a_sel = cr_simple_sel_append_simple_sel (*a_sel, sel); + + for (;;) { + guint32 next_char = 0; + enum Combinator comb = NO_COMBINATOR; + + sel = NULL; + + status = + cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, &next_char); + if (status == CR_END_OF_INPUT_ERROR) + break; + if (status != CR_OK) + goto error; + + if (next_char == '+') { + READ_NEXT_CHAR (a_this, &cur_char); + comb = COMB_PLUS; + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else if (next_char == '~') { + READ_NEXT_CHAR (a_this, &cur_char); + comb = COMB_TILDE; + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else if (next_char == '>') { + READ_NEXT_CHAR (a_this, &cur_char); + comb = COMB_GT; + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else { + comb = COMB_WS; + } + + status = cr_parser_parse_simple_selector (a_this, &sel); + if (status != CR_OK) + break; + + if (comb != NO_COMBINATOR && sel) { + sel->combinator = comb; + comb = NO_COMBINATOR; + } + if (sel) { + *a_sel = cr_simple_sel_append_simple_sel (*a_sel, + sel) ; + } + } + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_selector: + *@a_this: the current instance of #CRParser. + *@a_selector: the parsed list of comma separated + *selectors. + * + *Parses a comma separated list of selectors. + * + *Returns CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_parser_parse_selector (CRParser * a_this, + CRSelector ** a_selector) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRSimpleSel *simple_sels = NULL; + CRSelector *selector = NULL; + + g_return_val_if_fail (a_this && a_selector, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_simple_sels (a_this, &simple_sels); + CHECK_PARSING_STATUS (status, FALSE); + + if (simple_sels) { + selector = cr_selector_append_simple_sel + (selector, simple_sels); + if (selector) { + cr_parsing_location_copy + (&selector->location, + &simple_sels->location) ; + } + simple_sels = NULL; + } else { + status = CR_PARSING_ERROR ; + goto error ; + } + + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto okay; + } else { + goto error; + } + } + + if (next_char == ',') { + for (;;) { + simple_sels = NULL; + + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + break; + } else { + goto error; + } + } + + if (next_char != ',') + break; + + /*consume the ',' char */ + READ_NEXT_CHAR (a_this, &cur_char); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_simple_sels + (a_this, &simple_sels); + + CHECK_PARSING_STATUS (status, FALSE); + + if (simple_sels) { + selector = + cr_selector_append_simple_sel + (selector, simple_sels); + + simple_sels = NULL; + } + } + } + + okay: + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (!*a_selector) { + *a_selector = selector; + } else { + *a_selector = cr_selector_append (*a_selector, selector); + } + + selector = NULL; + return CR_OK; + + error: + + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_function: + *@a_this: the "this pointer" of the current instance of #CRParser. + * + *@a_func_name: out parameter. The parsed function name + *@a_expr: out parameter. The successfully parsed term. + * + *Parses a "function" as defined in css spec at appendix D.1: + *function ::= FUNCTION S* expr ')' S* + *FUNCTION ::= ident'(' + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_function (CRParser * a_this, + CRString ** a_func_name, + CRTerm ** a_expr) +{ + CRInputPos init_pos; + enum CRStatus status = CR_OK; + CRToken *token = NULL; + CRTerm *expr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_func_name, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + if (token && token->type == FUNCTION_TK) { + *a_func_name = token->u.str; + token->u.str = NULL; + } else { + status = CR_PARSING_ERROR; + goto error; + } + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_expr (a_this, &expr); + + CHECK_PARSING_STATUS (status, FALSE); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + ENSURE_PARSING_COND (token && token->type == PC_TK); + + cr_token_destroy (token); + token = NULL; + + if (expr) { + *a_expr = cr_term_append_term (*a_expr, expr); + expr = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (*a_func_name) { + cr_string_destroy (*a_func_name); + *a_func_name = NULL; + } + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (token) { + cr_token_destroy (token); + + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_uri: + *@a_this: the current instance of #CRParser. + *@a_str: the successfully parsed url. + * + *Parses an uri as defined by the css spec [4.1.1]: + * URI ::= url\({w}{string}{w}\) + * |url\({w}([!#$%&*-~]|{nonascii}|{escape})*{w}\) + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_uri (CRParser * a_this, CRString ** a_str) +{ + + enum CRStatus status = CR_PARSING_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + URI_TK, NO_ET, a_str, NULL); + return status; +} + +/** + * cr_parser_parse_string: + *@a_this: the current instance of #CRParser. + *@a_start: out parameter. Upon successful completion, + *points to the beginning of the string, points to an undefined value + *otherwise. + *@a_end: out parameter. Upon successful completion, points to + *the beginning of the string, points to an undefined value otherwise. + * + *Parses a string type as defined in css spec [4.1.1]: + * + *string ::= {string1}|{string2} + *string1 ::= \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" + *string2 ::= \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_string (CRParser * a_this, CRString ** a_str) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_str, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + STRING_TK, NO_ET, a_str, NULL); + return status; +} + +/** + *Parses an "ident" as defined in css spec [4.1.1]: + *ident ::= {nmstart}{nmchar}* + * + *@param a_this the currens instance of #CRParser. + * + *@param a_str a pointer to parsed ident. If *a_str is NULL, + *this function allocates a new instance of #CRString. If not, + *the function just appends the parsed string to the one passed. + *In both cases it is up to the caller to free *a_str. + * + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_ident (CRParser * a_this, CRString ** a_str) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_str, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + IDENT_TK, NO_ET, a_str, NULL); + return status; +} + +/** + *the next rule is ignored as well. This seems to be a bug + *Parses a stylesheet as defined in the css2 spec in appendix D.1: + *stylesheet ::= [ CHARSET_SYM S* STRING S* ';' ]? + * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* + * [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]* + * + *TODO: Finish the code of this function. Think about splitting it into + *smaller functions. + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_start out parameter. A pointer to the first character of + *the successfully parsed string. + *@param a_end out parameter. A pointer to the first character of + *the successfully parsed string. + * + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_stylesheet (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRString *charset = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PRIVATE (a_this)->state = READY_STATE; + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_document) { + PRIVATE (a_this)->sac_handler->start_document + (PRIVATE (a_this)->sac_handler); + } + + parse_charset: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token && token->type == CHARSET_SYM_TK) { + CRParsingLocation location = {0,0,0} ; + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_charset (a_this, + &charset, + &location); + + if (status == CR_OK && charset) { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->charset) { + PRIVATE (a_this)->sac_handler->charset + (PRIVATE (a_this)->sac_handler, + charset, &location); + } + } else if (status != CR_END_OF_INPUT_ERROR) { + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + } + + if (charset) { + cr_string_destroy (charset); + charset = NULL; + } + } else if (token + && (token->type == S_TK + || token->type == COMMENT_TK)) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto parse_charset ; + } else if (token) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + } + +/* parse_imports:*/ + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + } while (token + && (token->type == S_TK + || token->type == CDO_TK || token->type == CDC_TK)); + + if (token) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + } + + for (;;) { + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token && token->type == IMPORT_SYM_TK) { + GList *media_list = NULL; + CRString *import_string = NULL; + CRParsingLocation location = {0,0,0} ; + + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + + status = cr_parser_parse_import (a_this, + &media_list, + &import_string, + &location); + if (status == CR_OK) { + if (import_string + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->import_style) { + PRIVATE (a_this)->sac_handler->import_style + (PRIVATE(a_this)->sac_handler, + media_list, + import_string, + NULL, &location) ; + + if (PRIVATE (a_this)->sac_handler->resolve_import == TRUE) { + /* + *TODO: resolve the + *import rule. + */ + } + + if (PRIVATE (a_this)->sac_handler->import_style_result) { + PRIVATE (a_this)->sac_handler->import_style_result + (PRIVATE (a_this)->sac_handler, + media_list, import_string, + NULL, NULL); + } + } + } else if (status != CR_END_OF_INPUT_ERROR) { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler->error + (PRIVATE (a_this)->sac_handler); + } + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, TRUE) ; + } else { + goto error ; + } + + /* + *then, after calling the appropriate + *SAC handler, free + *the media_list and import_string. + */ + if (media_list) { + GList *cur = NULL; + + /*free the medium list */ + for (cur = media_list; cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy (cur->data); + } + } + + g_list_free (media_list); + media_list = NULL; + } + + if (import_string) { + cr_string_destroy (import_string); + import_string = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else if (token + && (token->type == S_TK + || token->type == CDO_TK + || token->type == CDC_TK)) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + } while (token + && (token->type == S_TK + || token->type == CDO_TK + || token->type == CDC_TK)); + } else { + if (token) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + goto parse_ruleset_and_others; + } + } + + parse_ruleset_and_others: + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + for (;;) { + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token + && (token->type == S_TK + || token->type == CDO_TK || token->type == CDC_TK)) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments + (a_this); + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + } while (token + && (token->type == S_TK + || token->type == COMMENT_TK + || token->type == CDO_TK + || token->type == CDC_TK)); + if (token) { + cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + } else if (token + && (token->type == HASH_TK + || (token->type == DELIM_TK + && token->u.unichar == '.') + || (token->type == DELIM_TK + && token->u.unichar == ':') + || (token->type == DELIM_TK + && token->u.unichar == '*') + || (token->type == BO_TK) + || token->type == IDENT_TK)) { + /* + *Try to parse a CSS2 ruleset. + *if the parsing fails, try to parse + *a css core ruleset. + */ + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_ruleset (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_ruleset_core + (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else if (token && token->type == MEDIA_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_media (a_this); + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + + } else if (token && token->type == PAGE_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_page (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else if (token && token->type == FONT_FACE_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_font_face (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_statement_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_END_OF_INPUT_ERROR || status == CR_OK) { + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_document) { + PRIVATE (a_this)->sac_handler->end_document + (PRIVATE (a_this)->sac_handler); + } + + return CR_OK; + } + + cr_parser_push_error + (a_this, (const guchar *) "could not recognize next production", CR_ERROR); + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->unrecoverable_error) { + PRIVATE (a_this)->sac_handler-> + unrecoverable_error (PRIVATE (a_this)->sac_handler); + } + + cr_parser_dump_err_stack (a_this, TRUE); + + return status; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->unrecoverable_error) { + PRIVATE (a_this)->sac_handler-> + unrecoverable_error (PRIVATE (a_this)->sac_handler); + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/**************************************** + *Public CRParser Methods + ****************************************/ + +/** + * cr_parser_new: + * @a_tknzr: the tokenizer to use for the parsing. + * + *Creates a new parser to parse data + *coming the input stream given in parameter. + * + *Returns the newly created instance of #CRParser, + *or NULL if an error occurred. + */ +CRParser * +cr_parser_new (CRTknzr * a_tknzr) +{ + CRParser *result = NULL; + enum CRStatus status = CR_OK; + + result = g_malloc0 (sizeof (CRParser)); + + PRIVATE (result) = g_malloc0 (sizeof (CRParserPriv)); + + if (a_tknzr) { + status = cr_parser_set_tknzr (result, a_tknzr); + if (status != CR_OK) + cr_parser_destroy (result); + } + + g_return_val_if_fail (status == CR_OK, NULL); + + return result; +} + +/** + * cr_parser_new_from_buf: + *@a_buf: the buffer to parse. + *@a_len: the length of the data in the buffer. + *@a_enc: the encoding of the input buffer a_buf. + *@a_free_buf: if set to TRUE, a_buf will be freed + *during the destruction of the newly built instance + *of #CRParser. If set to FALSE, it is up to the caller to + *eventually free it. + * + *Instantiates a new parser from a memory buffer. + * + *Returns the newly built parser, or NULL if an error arises. + */ +CRParser * +cr_parser_new_from_buf (guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) +{ + CRParser *result = NULL; + CRInput *input = NULL; + + g_return_val_if_fail (a_buf, NULL); + + input = cr_input_new_from_buf (a_buf, a_len, a_enc, a_free_buf); + g_return_val_if_fail (input, NULL); + + result = cr_parser_new_from_input (input); + if (!result) { + cr_input_destroy (input); + input = NULL; + return NULL; + } + return result; +} + +/** + * cr_parser_new_from_input: + * @a_input: the parser input stream to use. + * + * Returns a newly built parser input. + */ +CRParser * +cr_parser_new_from_input (CRInput * a_input) +{ + CRParser *result = NULL; + CRTknzr *tokenizer = NULL; + + if (a_input) { + tokenizer = cr_tknzr_new (a_input); + g_return_val_if_fail (tokenizer, NULL); + } + + result = cr_parser_new (tokenizer); + if (!result) + g_clear_pointer (&tokenizer, cr_tknzr_unref); + g_return_val_if_fail (result, NULL); + + return result; +} + +/** + * cr_parser_new_from_file: + * @a_file_uri: the uri of the file to parse. + * @a_enc: the file encoding to use. + * + * Returns the newly built parser. + */ +CRParser * +cr_parser_new_from_file (const guchar * a_file_uri, enum CREncoding a_enc) +{ + CRParser *result = NULL; + CRTknzr *tokenizer = NULL; + + tokenizer = cr_tknzr_new_from_uri (a_file_uri, a_enc); + if (!tokenizer) { + cr_utils_trace_info ("Could not open input file"); + return NULL; + } + + result = cr_parser_new (tokenizer); + if (!result) + g_clear_pointer (&tokenizer, cr_tknzr_unref); + g_return_val_if_fail (result, NULL); + return result; +} + +/** + * cr_parser_set_sac_handler: + *@a_this: the "this pointer" of the current instance of #CRParser. + *@a_handler: the handler to set. + * + *Sets a SAC document handler to the parser. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_sac_handler (CRParser * a_this, CRDocHandler * a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->sac_handler) { + cr_doc_handler_unref (PRIVATE (a_this)->sac_handler); + } + + PRIVATE (a_this)->sac_handler = a_handler; + cr_doc_handler_ref (a_handler); + + return CR_OK; +} + +/** + * cr_parser_get_sac_handler: + *@a_this: the "this pointer" of the current instance of + *#CRParser. + *@a_handler: out parameter. The returned handler. + * + *Gets the SAC document handler. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_parser_get_sac_handler (CRParser * a_this, CRDocHandler ** a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + *a_handler = PRIVATE (a_this)->sac_handler; + + return CR_OK; +} + +/** + * cr_parser_set_default_sac_handler: + *@a_this: a pointer to the current instance of #CRParser. + * + *Sets the SAC handler associated to the current instance + *of #CRParser to the default SAC handler. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_default_sac_handler (CRParser * a_this) +{ + CRDocHandler *default_sac_handler = NULL; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + default_sac_handler = cr_doc_handler_new (); + + cr_doc_handler_set_default_sac_handler (default_sac_handler); + + status = cr_parser_set_sac_handler (a_this, default_sac_handler); + + if (status != CR_OK) { + cr_doc_handler_destroy (default_sac_handler); + default_sac_handler = NULL; + } + + return status; +} + +/** + * cr_parser_set_use_core_grammar: + * @a_this: the current instance of #CRParser. + * @a_use_core_grammar: where to parse against the css core grammar. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_use_core_grammar (CRParser * a_this, + gboolean a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->use_core_grammar = a_use_core_grammar; + + return CR_OK; +} + +/** + * cr_parser_get_use_core_grammar: + * @a_this: the current instance of #CRParser. + * @a_use_core_grammar: whether to use the core grammar or not. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_get_use_core_grammar (CRParser const * a_this, + gboolean * a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + *a_use_core_grammar = PRIVATE (a_this)->use_core_grammar; + + return CR_OK; +} + +/** + * cr_parser_parse_file: + *@a_this: a pointer to the current instance of #CRParser. + *@a_file_uri: the uri to the file to load. For the time being, + *@a_enc: the encoding of the file to parse. + *only local files are supported. + * + *Parses a the given in parameter. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_file (CRParser * a_this, + const guchar * a_file_uri, enum CREncoding a_enc) +{ + enum CRStatus status = CR_ERROR; + CRTknzr *tknzr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_file_uri, CR_BAD_PARAM_ERROR); + + tknzr = cr_tknzr_new_from_uri (a_file_uri, a_enc); + + g_return_val_if_fail (tknzr != NULL, CR_ERROR); + + status = cr_parser_set_tknzr (a_this, tknzr); + if (status != CR_OK) + g_clear_pointer (&tknzr, cr_tknzr_unref); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + + status = cr_parser_parse (a_this); + + return status; +} + +/** + * cr_parser_parse_expr: + * @a_this: the current instance of #CRParser. + * @a_expr: out parameter. the parsed expression. + * + *Parses an expression as defined by the css2 spec in appendix + *D.1: + *expr: term [ operator term ]* + * + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_expr (CRParser * a_this, CRTerm ** a_expr) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRTerm *expr = NULL, + *expr2 = NULL; + guchar next_byte = 0; + gulong nb_terms = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_expr, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_term (a_this, &expr); + + CHECK_PARSING_STATUS (status, FALSE); + + for (;;) { + guchar operatr = 0; + + status = cr_tknzr_peek_byte (PRIVATE (a_this)->tknzr, + 1, &next_byte); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + /* + if (!nb_terms) + { + goto error ; + } + */ + status = CR_OK; + break; + } else { + goto error; + } + } + + if (next_byte == '/' || next_byte == ',') { + READ_NEXT_BYTE (a_this, &operatr); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_term (a_this, &expr2); + + if (status != CR_OK || expr2 == NULL) { + status = CR_OK; + break; + } + + switch (operatr) { + case '/': + expr2->the_operator = DIVIDE; + break; + case ',': + expr2->the_operator = COMMA; + + default: + break; + } + + expr = cr_term_append_term (expr, expr2); + expr2 = NULL; + operatr = 0; + nb_terms++; + } + + if (status == CR_OK) { + *a_expr = cr_term_append_term (*a_expr, expr); + expr = NULL; + + cr_parser_clear_errors (a_this); + return CR_OK; + } + + error: + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (expr2) { + cr_term_destroy (expr2); + expr2 = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_prio: + *@a_this: the current instance of #CRParser. + *@a_prio: a string representing the priority. + *Today, only "!important" is returned as only this + *priority is defined by css2. + * + *Parses a declaration priority as defined by + *the css2 grammar in appendix C: + *prio: IMPORTANT_SYM S* + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_prio (CRParser * a_this, CRString ** a_prio) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prio + && *a_prio == NULL, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) { + goto error; + } + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IMPORTANT_SYM_TK); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + *a_prio = cr_string_new_from_string ("!important"); + cr_token_destroy (token); + token = NULL; + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_declaration: + *@a_this: the "this pointer" of the current instance of #CRParser. + *@a_property: the successfully parsed property. The caller + * *must* free the returned pointer. + *@a_expr: the expression that represents the attribute value. + *The caller *must* free the returned pointer. + * + *TODO: return the parsed priority, so that + *upper layers can take benefit from it. + *Parses a "declaration" as defined by the css2 spec in appendix D.1: + *declaration ::= [property ':' S* expr prio?]? + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_declaration (CRParser * a_this, + CRString ** a_property, + CRTerm ** a_expr, gboolean * a_important) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + guint32 cur_char = 0; + CRTerm *expr = NULL; + CRString *prio = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_property && a_expr + && a_important, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_property (a_this, a_property); + + if (status == CR_END_OF_INPUT_ERROR) + goto error; + + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + (const guchar *) "while parsing declaration: next property is malformed", + CR_SYNTAX_ERROR); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != ':') { + status = CR_PARSING_ERROR; + cr_parser_push_error + (a_this, + (const guchar *) "while parsing declaration: this char must be ':'", + CR_SYNTAX_ERROR); + goto error; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_expr (a_this, &expr); + + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + (const guchar *) "while parsing declaration: next expression is malformed", + CR_SYNTAX_ERROR); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_prio (a_this, &prio); + if (prio) { + cr_string_destroy (prio); + prio = NULL; + *a_important = TRUE; + } else { + *a_important = FALSE; + } + if (*a_expr) { + cr_term_append_term (*a_expr, expr); + expr = NULL; + } else { + *a_expr = expr; + expr = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (*a_property) { + cr_string_destroy (*a_property); + *a_property = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_statement_core: + *@a_this: the current instance of #CRParser. + * + *Parses a statement as defined by the css core grammar in + *chapter 4.1 of the css2 spec. + *statement : ruleset | at-rule; + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_statement_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token); + + switch (token->type) { + case ATKEYWORD_TK: + case IMPORT_SYM_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, TRUE); + break; + + default: + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_ruleset_core (a_this); + cr_parser_clear_errors (a_this); + CHECK_PARSING_STATUS (status, TRUE); + } + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_ruleset: + *@a_this: the "this pointer" of the current instance of #CRParser. + * + *Parses a "ruleset" as defined in the css2 spec at appendix D.1. + *ruleset ::= selector [ ',' S* selector ]* + *'{' S* declaration? [ ';' S* declaration? ]* '}' S*; + * + *This methods calls the SAC handler on the relevant SAC handler + *callbacks whenever it encounters some specific constructions. + *See the documentation of #CRDocHandler (the SAC handler) to know + *when which SAC handler is called. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_ruleset (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRString *property = NULL; + CRTerm *expr = NULL; + CRSimpleSel *simple_sels = NULL; + CRSelector *selector = NULL; + gboolean start_selector = FALSE, + is_important = FALSE; + CRParsingLocation end_parsing_location; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_selector (a_this, &selector); + CHECK_PARSING_STATUS (status, FALSE); + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND_ERR + (a_this, cur_char == '{', + (const guchar *) "while parsing rulset: current char should be '{'", + CR_SYNTAX_ERROR); + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_selector) { + /* + *the selector is ref counted so that the parser's user + *can choose to keep it. + */ + if (selector) { + cr_selector_ref (selector); + } + + PRIVATE (a_this)->sac_handler->start_selector + (PRIVATE (a_this)->sac_handler, selector); + start_selector = TRUE; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_RULESET_STATE; + + status = cr_parser_parse_declaration (a_this, &property, + &expr, + &is_important); + if (expr) { + cr_term_ref (expr); + } + if (status == CR_OK + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, property, expr, + is_important); + } + if (status == CR_OK) { + /* + *free the allocated + *'property' and 'term' before parsing + *next declarations. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + } else {/*status != CR_OK*/ + guint32 c = 0 ; + /* + *test if we have reached '}', which + *would mean that we are parsing an empty ruleset (eg. x{ }) + *In that case, goto end_of_ruleset. + */ + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, &c) ; + if (status == CR_OK && c == '}') { + status = CR_OK ; + goto end_of_ruleset ; + } + } + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + (const guchar *) "while parsing ruleset: next construction should be a declaration", + CR_SYNTAX_ERROR); + + for (;;) { + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char != ';') + break; + + /*consume the ';' char */ + READ_NEXT_CHAR (a_this, &cur_char); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_declaration (a_this, &property, + &expr, &is_important); + + if (expr) { + cr_term_ref (expr); + } + if (status == CR_OK + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, expr, is_important); + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + } + + end_of_ruleset: + cr_parser_try_to_skip_spaces_and_comments (a_this); + cr_parser_get_parsing_location (a_this, &end_parsing_location); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND_ERR + (a_this, cur_char == '}', + (const guchar *) "while parsing rulset: current char must be a '}'", + CR_SYNTAX_ERROR); + + selector->location = end_parsing_location; + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_selector) { + PRIVATE (a_this)->sac_handler->end_selector + (PRIVATE (a_this)->sac_handler, selector); + start_selector = FALSE; + } + + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = RULESET_PARSED_STATE; + + return CR_OK; + + error: + if (start_selector == TRUE + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler->error + (PRIVATE (a_this)->sac_handler); + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + if (property) { + cr_string_destroy (property); + } + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_import: + *@a_this: the "this pointer" of the current instance + *of #CRParser. + *@a_media_list: out parameter. A linked list of + *#CRString + *Each CRString is a string that contains + *a 'medium' declaration part of the successfully + *parsed 'import' declaration. + *@a_import_string: out parameter. + *A string that contains the 'import + *string". The import string can be either an uri (if it starts with + *the substring "uri(") or a any other css2 string. Note that + * *a_import_string must be initially set to NULL or else, this function + *will return CR_BAD_PARAM_ERROR. + *@a_location: the location (line, column) where the import has been parsed + * + *Parses an 'import' declaration as defined in the css2 spec + *in appendix D.1: + * + *import ::= + *\@import [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S* + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_import (CRParser * a_this, + GList ** a_media_list, + CRString ** a_import_string, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRString *medium = NULL; + + g_return_val_if_fail (a_this + && a_import_string + && (*a_import_string == NULL), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + if (BYTE (a_this, 1, NULL) == '@' + && BYTE (a_this, 2, NULL) == 'i' + && BYTE (a_this, 3, NULL) == 'm' + && BYTE (a_this, 4, NULL) == 'p' + && BYTE (a_this, 5, NULL) == 'o' + && BYTE (a_this, 6, NULL) == 'r' + && BYTE (a_this, 7, NULL) == 't') { + SKIP_CHARS (a_this, 1); + if (a_location) { + cr_parser_get_parsing_location + (a_this, a_location) ; + } + SKIP_CHARS (a_this, 6); + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_IMPORT_STATE; + + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '"' || next_char == '\'') { + status = cr_parser_parse_string (a_this, a_import_string); + + CHECK_PARSING_STATUS (status, FALSE); + } else { + status = cr_parser_parse_uri (a_this, a_import_string); + + CHECK_PARSING_STATUS (status, FALSE); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + if (status == CR_OK && medium) { + *a_media_list = g_list_append (*a_media_list, medium); + medium = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + for (; status == CR_OK;) { + if ((status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char)) != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto okay; + } + goto error; + } + + if (next_char == ',') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if ((status == CR_OK) && medium) { + *a_media_list = g_list_append (*a_media_list, medium); + + medium = NULL; + } + + CHECK_PARSING_STATUS (status, FALSE); + cr_parser_try_to_skip_spaces_and_comments (a_this); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == ';'); + cr_parser_try_to_skip_spaces_and_comments (a_this); + okay: + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = IMPORT_PARSED_STATE; + + return CR_OK; + + error: + + if (*a_media_list) { + GList *cur = NULL; + + /* + *free each element of *a_media_list. + *Note that each element of *a_medium list *must* + *be a GString* or else, the code that is coming next + *will corrupt the memory and lead to hard to debug + *random crashes. + *This is where C++ and its compile time + *type checking mechanism (through STL containers) would + *have prevented us to go through this hassle. + */ + for (cur = *a_media_list; cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy (cur->data); + } + } + + g_list_free (*a_media_list); + *a_media_list = NULL; + } + + if (*a_import_string) { + cr_string_destroy (*a_import_string); + *a_import_string = NULL; + } + + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_media: + *@a_this: the "this pointer" of the current instance of #CRParser. + * + *Parses a 'media' declaration as specified in the css2 spec at + *appendix D.1: + * + *media ::= \@media S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S* + * + *Note that this function calls the required sac handlers during the parsing + *to notify media productions. See #CRDocHandler to know the callback called + *during \@media parsing. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_media (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + guint32 next_char = 0, + cur_char = 0; + CRString *medium = NULL; + GList *media_list = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this + && PRIVATE (a_this), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == MEDIA_SYM_TK); + cr_parsing_location_copy (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IDENT_TK); + + medium = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + if (medium) { + media_list = g_list_append (media_list, medium); + medium = NULL; + } + + for (; status == CR_OK;) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == ',') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + CHECK_PARSING_STATUS (status, FALSE); + + if (medium) { + media_list = g_list_append (media_list, medium); + medium = NULL; + } + } + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND (cur_char == '{'); + + /* + *call the SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_media) { + PRIVATE (a_this)->sac_handler->start_media + (PRIVATE (a_this)->sac_handler, media_list, + &location); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_MEDIA_STATE; + + for (; status == CR_OK;) { + status = cr_parser_parse_ruleset (a_this); + cr_parser_try_to_skip_spaces_and_comments (a_this); + } + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND (cur_char == '}'); + + /* + *call the right SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_media) { + PRIVATE (a_this)->sac_handler->end_media + (PRIVATE (a_this)->sac_handler, media_list); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + /* + *Then, free the data structures passed to + *the last call to the SAC handler. + */ + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + if (media_list) { + GList *cur = NULL; + + for (cur = media_list; cur; cur = cur->next) { + cr_string_destroy (cur->data); + } + + g_list_free (media_list); + media_list = NULL; + } + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = MEDIA_PARSED_STATE; + + return CR_OK; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + if (media_list) { + GList *cur = NULL; + + for (cur = media_list; cur; cur = cur->next) { + cr_string_destroy (cur->data); + } + + g_list_free (media_list); + media_list = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_page: + *@a_this: the "this pointer" of the current instance of #CRParser. + * + *Parses '\@page' rule as specified in the css2 spec in appendix D.1: + *page ::= PAGE_SYM S* IDENT? pseudo_page? S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function also calls the relevant SAC handlers whenever it + *encounters a construction that must + *be reported to the calling application. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_page (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRTerm *css_expression = NULL; + CRString *page_selector = NULL, + *page_pseudo_class = NULL, + *property = NULL; + gboolean important = TRUE; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == PAGE_SYM_TK); + + cr_parsing_location_copy (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == IDENT_TK) { + page_selector = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + + /* + *try to parse pseudo_page + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == DELIM_TK && token->u.unichar == ':') { + cr_token_destroy (token); + token = NULL; + status = cr_parser_parse_ident (a_this, &page_pseudo_class); + CHECK_PARSING_STATUS (status, FALSE); + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + + /* + *parse_block + * + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + + cr_token_destroy (token); + token = NULL; + + /* + *Call the appropriate SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_page) { + PRIVATE (a_this)->sac_handler->start_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class, + &location); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_PAGE_STATE; + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, + &important); + ENSURE_PARSING_COND (status == CR_OK); + + /* + *call the relevant SAC handler here... + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + if (css_expression) + cr_term_ref (css_expression); + + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *... and free the data structure passed to that last + *SAC handler. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + + for (;;) { + /*parse the other ';' separated declarations */ + if (token) { + cr_token_destroy (token); + token = NULL; + } + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type != SEMICOLON_TK) { + cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, + token); + token = NULL ; + break; + } + + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, + &important); + if (status != CR_OK) + break ; + + /* + *call the relevant SAC handler here... + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + cr_term_ref (css_expression); + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *... and free the data structure passed to that last + *SAC handler. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + } + cr_parser_try_to_skip_spaces_and_comments + (a_this) ; + if (token) { + cr_token_destroy (token) ; + token = NULL ; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == CBC_TK) ; + cr_token_destroy (token) ; + token = NULL ; + /* + *call the relevant SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_page) { + PRIVATE (a_this)->sac_handler->end_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class); + } + + if (page_selector) { + cr_string_destroy (page_selector); + page_selector = NULL; + } + + if (page_pseudo_class) { + cr_string_destroy (page_pseudo_class); + page_pseudo_class = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + /*here goes the former implem of this function ... */ + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = PAGE_PARSED_STATE; + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + if (page_selector) { + cr_string_destroy (page_selector); + page_selector = NULL; + } + if (page_pseudo_class) { + cr_string_destroy (page_pseudo_class); + page_pseudo_class = NULL; + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_destroy (css_expression); + css_expression = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + * cr_parser_parse_charset: + *@a_this: the "this pointer" of the current instance of #CRParser. + *@a_value: out parameter. The actual parsed value of the charset + *declararation. Note that for safety check reasons, *a_value must be + *set to NULL. + *@a_charset_sym_location: the parsing location of the charset rule + * + *Parses a charset declaration as defined implicitly by the css2 spec in + *appendix D.1: + *charset ::= CHARSET_SYM S* STRING S* ';' + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_charset (CRParser * a_this, CRString ** a_value, + CRParsingLocation *a_charset_sym_location) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRString *charset_str = NULL; + + g_return_val_if_fail (a_this && a_value + && (*a_value == NULL), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == CHARSET_SYM_TK); + if (a_charset_sym_location) { + cr_parsing_location_copy (a_charset_sym_location, + &token->location) ; + } + cr_token_destroy (token); + token = NULL; + + PRIVATE (a_this)->state = TRY_PARSE_CHARSET_STATE; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == STRING_TK); + charset_str = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == SEMICOLON_TK); + cr_token_destroy (token); + token = NULL; + + if (charset_str) { + *a_value = charset_str; + charset_str = NULL; + } + + PRIVATE (a_this)->state = CHARSET_PARSED_STATE; + return CR_OK; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (*a_value) { + cr_string_destroy (*a_value); + *a_value = NULL; + } + + if (charset_str) { + cr_string_destroy (charset_str); + charset_str = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + * cr_parser_parse_font_face: + *@a_this: the current instance of #CRParser. + * + *Parses the "\@font-face" rule specified in the css1 spec in + *appendix D.1: + * + *font_face ::= FONT_FACE_SYM S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function will call SAC handlers whenever it is necessary. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_font_face (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRString *property = NULL; + CRTerm *css_expression = NULL; + CRToken *token = NULL; + gboolean important = FALSE; + guint32 next_char = 0, + cur_char = 0; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == FONT_FACE_SYM_TK); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + if (token) { + cr_parsing_location_copy (&location, + &token->location) ; + cr_token_destroy (token); + token = NULL; + } + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + if (token) { + cr_token_destroy (token); + token = NULL; + } + /* + *here, call the relevant SAC handler. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_font_face) { + PRIVATE (a_this)->sac_handler->start_font_face + (PRIVATE (a_this)->sac_handler, &location); + } + PRIVATE (a_this)->state = TRY_PARSE_FONT_FACE_STATE; + /* + *and resume the parsing. + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, &important); + if (status == CR_OK) { + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression); + if (PRIVATE (a_this)->sac_handler && + PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + ENSURE_PARSING_COND (css_expression && property); + } + /*free the data structures allocated during last parsing. */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + for (;;) { + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == ';') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration (a_this, + &property, + &css_expression, + &important); + if (status != CR_OK) + break; + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression); + if (PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *Then, free the data structures allocated during + *last parsing. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '}'); + /* + *here, call the relevant SAC handler. + */ + if (PRIVATE (a_this)->sac_handler->end_font_face) { + PRIVATE (a_this)->sac_handler->end_font_face + (PRIVATE (a_this)->sac_handler); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = FONT_FACE_PARSED_STATE; + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_destroy (css_expression); + css_expression = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + * cr_parser_parse: + *@a_this: the current instance of #CRParser. + * + *Parses the data that comes from the + *input previously associated to the current instance of + *#CRParser. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->use_core_grammar == FALSE) { + status = cr_parser_parse_stylesheet (a_this); + } else { + status = cr_parser_parse_stylesheet_core (a_this); + } + + return status; +} + +/** + * cr_parser_set_tknzr: + * @a_this: the current instance of #CRParser; + * @a_tknzr: the new tokenizer. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_tknzr (CRParser * a_this, CRTknzr * a_tknzr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->tknzr) { + cr_tknzr_unref (PRIVATE (a_this)->tknzr); + } + + PRIVATE (a_this)->tknzr = a_tknzr; + + if (a_tknzr) + cr_tknzr_ref (a_tknzr); + + return CR_OK; +} + +/** + * cr_parser_get_tknzr: + *@a_this: the current instance of #CRParser + *@a_tknzr: out parameter. The returned tokenizer + * + *Getter of the parser's underlying tokenizer + * + *Returns CR_OK upon successful completion, an error code + *otherwise + */ +enum CRStatus +cr_parser_get_tknzr (CRParser * a_this, CRTknzr ** a_tknzr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_tknzr, CR_BAD_PARAM_ERROR); + + *a_tknzr = PRIVATE (a_this)->tknzr; + return CR_OK; +} + +/** + * cr_parser_get_parsing_location: + *@a_this: the current instance of #CRParser + *@a_loc: the parsing location to get. + * + *Gets the current parsing location. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_parser_get_parsing_location (CRParser const *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, CR_BAD_PARAM_ERROR) ; + + return cr_tknzr_get_parsing_location + (PRIVATE (a_this)->tknzr, a_loc) ; +} + +/** + * cr_parser_parse_buf: + *@a_this: the current instance of #CRparser + *@a_buf: the input buffer + *@a_len: the length of the input buffer + *@a_enc: the encoding of the buffer + * + *Parses a stylesheet from a buffer + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_buf (CRParser * a_this, + const guchar * a_buf, + gulong a_len, enum CREncoding a_enc) +{ + enum CRStatus status = CR_ERROR; + CRTknzr *tknzr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_buf, CR_BAD_PARAM_ERROR); + + tknzr = cr_tknzr_new_from_buf ((guchar*)a_buf, a_len, a_enc, FALSE); + + g_return_val_if_fail (tknzr != NULL, CR_ERROR); + + status = cr_parser_set_tknzr (a_this, tknzr); + if (status != CR_OK) + g_clear_pointer (&tknzr, cr_tknzr_unref); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + + status = cr_parser_parse (a_this); + + return status; +} + +/** + * cr_parser_destroy: + *@a_this: the current instance of #CRParser to + *destroy. + * + *Destroys the current instance + *of #CRParser. + */ +void +cr_parser_destroy (CRParser * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->tknzr) { + if (cr_tknzr_unref (PRIVATE (a_this)->tknzr) == TRUE) + PRIVATE (a_this)->tknzr = NULL; + } + + if (PRIVATE (a_this)->sac_handler) { + cr_doc_handler_unref (PRIVATE (a_this)->sac_handler); + PRIVATE (a_this)->sac_handler = NULL; + } + + if (PRIVATE (a_this)->err_stack) { + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->err_stack = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-parser.h b/src/3rdparty/libcroco/src/cr-parser.h new file mode 100644 index 0000000..24cf5df --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-parser.h @@ -0,0 +1,130 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_PARSER_H__ +#define __CR_PARSER_H__ + +#include <glib.h> +#include "cr-input.h" +#include "cr-tknzr.h" +#include "cr-utils.h" +#include "cr-doc-handler.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration file + *of the #CRParser class. + */ +typedef struct _CRParser CRParser ; +typedef struct _CRParserPriv CRParserPriv ; + + +/** + *The implementation of + *the SAC parser. + *The Class is opaque + *and must be manipulated through + *the provided methods. + */ +struct _CRParser { + CRParserPriv *priv ; +} ; + + +CRParser * cr_parser_new (CRTknzr *a_tknzr) ; + +CRParser * cr_parser_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) ; + +CRParser * cr_parser_new_from_file (const guchar *a_file_uri, + enum CREncoding a_enc) ; + +CRParser * cr_parser_new_from_input (CRInput *a_input) ; + +enum CRStatus cr_parser_set_tknzr (CRParser *a_this, CRTknzr *a_tknzr) ; + +enum CRStatus cr_parser_get_tknzr (CRParser *a_this, CRTknzr **a_tknzr) ; + +enum CRStatus cr_parser_get_parsing_location (CRParser const *a_this, CRParsingLocation *a_loc) ; + +enum CRStatus cr_parser_try_to_skip_spaces_and_comments (CRParser *a_this) ; + + +enum CRStatus cr_parser_set_sac_handler (CRParser *a_this, + CRDocHandler *a_handler) ; + +enum CRStatus cr_parser_get_sac_handler (CRParser *a_this, + CRDocHandler **a_handler) ; + +enum CRStatus cr_parser_set_use_core_grammar (CRParser *a_this, + gboolean a_use_core_grammar) ; +enum CRStatus cr_parser_get_use_core_grammar (CRParser const *a_this, + gboolean *a_use_core_grammar) ; + +enum CRStatus cr_parser_parse (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_file (CRParser *a_this, + const guchar *a_file_uri, + enum CREncoding a_enc) ; + +enum CRStatus cr_parser_parse_buf (CRParser *a_this, const guchar *a_buf, + gulong a_len, enum CREncoding a_enc) ; + +enum CRStatus cr_parser_set_default_sac_handler (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_term (CRParser *a_this, CRTerm **a_term) ; + +enum CRStatus cr_parser_parse_selector (CRParser * a_this, CRSelector ** a_selector) ; + +enum CRStatus cr_parser_parse_expr (CRParser *a_this, CRTerm **a_expr) ; + +enum CRStatus cr_parser_parse_prio (CRParser *a_this, CRString **a_prio) ; + +enum CRStatus cr_parser_parse_declaration (CRParser *a_this, CRString **a_property, + CRTerm **a_expr, gboolean *a_important) ; + +enum CRStatus cr_parser_parse_statement_core (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_ruleset (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_import (CRParser *a_this, GList ** a_media_list, + CRString **a_import_string, + CRParsingLocation *a_location) ; + +enum CRStatus cr_parser_parse_media (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_page (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_charset (CRParser *a_this, CRString **a_value, + CRParsingLocation *a_charset_sym_location) ; + +enum CRStatus cr_parser_parse_font_face (CRParser *a_this) ; + +void cr_parser_destroy (CRParser *a_this) ; + +G_END_DECLS + +#endif /*__CR_PARSER_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-parsing-location.c b/src/3rdparty/libcroco/src/cr-parsing-location.c new file mode 100644 index 0000000..0aa0a45 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-parsing-location.c @@ -0,0 +1,172 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See the COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-parsing-location.h" + +/** + *@CRParsingLocation: + * + *Definition of the #CRparsingLocation class. + */ + + +/** + * cr_parsing_location_new: + *Instantiates a new parsing location. + * + *Returns the newly instantiated #CRParsingLocation. + *Must be freed by cr_parsing_location_destroy() + */ +CRParsingLocation * +cr_parsing_location_new (void) +{ + CRParsingLocation * result = NULL ; + + result = g_try_malloc (sizeof (CRParsingLocation)) ; + if (!result) { + cr_utils_trace_info ("Out of memory error") ; + return NULL ; + } + cr_parsing_location_init (result) ; + return result ; +} + +/** + * cr_parsing_location_init: + *@a_this: the current instance of #CRParsingLocation. + * + *Initializes the an instance of #CRparsingLocation. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parsing_location_init (CRParsingLocation *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + memset (a_this, 0, sizeof (CRParsingLocation)) ; + return CR_OK ; +} + +/** + * cr_parsing_location_copy: + *@a_to: the destination of the copy. + *Must be allocated by the caller. + *@a_from: the source of the copy. + * + *Copies an instance of CRParsingLocation into another one. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_parsing_location_copy (CRParsingLocation *a_to, + CRParsingLocation const *a_from) +{ + g_return_val_if_fail (a_to && a_from, CR_BAD_PARAM_ERROR) ; + + memcpy (a_to, a_from, sizeof (CRParsingLocation)) ; + return CR_OK ; +} + +/** + * cr_parsing_location_to_string: + *@a_this: the current instance of #CRParsingLocation. + *@a_mask: a bitmap that defines which parts of the + *parsing location are to be serialized (line, column or byte offset) + * + *Returns the serialized string or NULL in case of an error. + */ +gchar * +cr_parsing_location_to_string (CRParsingLocation const *a_this, + enum CRParsingLocationSerialisationMask a_mask) +{ + GString *result = NULL ; + gchar *str = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + if (!a_mask) { + a_mask = DUMP_LINE | DUMP_COLUMN | DUMP_BYTE_OFFSET ; + } + result =g_string_new (NULL) ; + if (!result) + return NULL ; + if (a_mask & DUMP_LINE) { + g_string_append_printf (result, "line:%d ", + a_this->line) ; + } + if (a_mask & DUMP_COLUMN) { + g_string_append_printf (result, "column:%d ", + a_this->column) ; + } + if (a_mask & DUMP_BYTE_OFFSET) { + g_string_append_printf (result, "byte offset:%d ", + a_this->byte_offset) ; + } + if (result->len) { + str = result->str ; + g_string_free (result, FALSE) ; + } else { + g_string_free (result, TRUE) ; + } + return str ; +} + +/** + * cr_parsing_location_dump: + * @a_this: current instance of #CRParsingLocation + * @a_mask: the serialization mask. + * @a_fp: the file pointer to dump the parsing location to. + */ +void +cr_parsing_location_dump (CRParsingLocation const *a_this, + enum CRParsingLocationSerialisationMask a_mask, + FILE *a_fp) +{ + gchar *str = NULL ; + + g_return_if_fail (a_this && a_fp) ; + str = cr_parsing_location_to_string (a_this, a_mask) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + * cr_parsing_location_destroy: + *@a_this: the current instance of #CRParsingLocation. Must + *have been allocated with cr_parsing_location_new(). + * + *Destroys the current instance of #CRParsingLocation + */ +void +cr_parsing_location_destroy (CRParsingLocation *a_this) +{ + g_return_if_fail (a_this) ; + g_free (a_this) ; +} + diff --git a/src/3rdparty/libcroco/src/cr-parsing-location.h b/src/3rdparty/libcroco/src/cr-parsing-location.h new file mode 100644 index 0000000..b8064a5 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-parsing-location.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_PARSING_LOCATION_H__ +#define __CR_PARSING_LOCATION_H__ + +#include "cr-utils.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the CRParsingLocation + *object. This object keeps track of line/column/byte offset/ + *at which the parsing of a given CSS construction appears. + */ + +typedef struct _CRParsingLocation CRParsingLocation; +struct _CRParsingLocation { + guint line ; + guint column ; + guint byte_offset ; +} ; + + +enum CRParsingLocationSerialisationMask { + DUMP_LINE = 1, + DUMP_COLUMN = 1 << 1, + DUMP_BYTE_OFFSET = 1 << 2 +} ; + +CRParsingLocation * cr_parsing_location_new (void) ; + +enum CRStatus cr_parsing_location_init (CRParsingLocation *a_this) ; + +enum CRStatus cr_parsing_location_copy (CRParsingLocation *a_to, + CRParsingLocation const *a_from) ; + +gchar * cr_parsing_location_to_string (CRParsingLocation const *a_this, + enum CRParsingLocationSerialisationMask a_mask) ; +void cr_parsing_location_dump (CRParsingLocation const *a_this, + enum CRParsingLocationSerialisationMask a_mask, + FILE *a_fp) ; + +void cr_parsing_location_destroy (CRParsingLocation *a_this) ; + + + +G_END_DECLS +#endif diff --git a/src/3rdparty/libcroco/src/cr-prop-list.c b/src/3rdparty/libcroco/src/cr-prop-list.c new file mode 100644 index 0000000..8e42cee --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-prop-list.c @@ -0,0 +1,404 @@ +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#include <string.h> +#include "cr-prop-list.h" + +#define PRIVATE(a_obj) (a_obj)->priv + +struct _CRPropListPriv { + CRString *prop; + CRDeclaration *decl; + CRPropList *next; + CRPropList *prev; +}; + +static CRPropList *cr_prop_list_allocate (void); + +/** + *Default allocator of CRPropList + *@return the newly allocated CRPropList or NULL + *if an error arises. + */ +static CRPropList * +cr_prop_list_allocate (void) +{ + CRPropList *result = NULL; + + result = g_try_malloc (sizeof (CRPropList)); + if (!result) { + cr_utils_trace_info ("could not allocate CRPropList"); + return NULL; + } + memset (result, 0, sizeof (CRPropList)); + PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("could not allocate CRPropListPriv"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRPropListPriv)); + return result; +} + +/**************** + *public methods + ***************/ + +/** + * cr_prop_list_append: + *@a_this: the current instance of #CRPropList + *@a_to_append: the property list to append + * + *Appends a property list to the current one. + * + *Returns the resulting prop list, or NULL if an error + *occurred + */ +CRPropList * +cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_append, NULL); + + if (!a_this) + return a_to_append; + + /*go fetch the last element of the list */ + for (cur = a_this; + cur && PRIVATE (cur) && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_to_append; + PRIVATE (a_to_append)->prev = cur; + return a_this; +} + +/** + * cr_prop_list_append2: + *Appends a pair of prop/declaration to + *the current prop list. + *@a_this: the current instance of #CRPropList + *@a_prop: the property to consider + *@a_decl: the declaration to consider + * + *Returns the resulting property list, or NULL in case + *of an error. + */ +CRPropList * +cr_prop_list_append2 (CRPropList * a_this, + CRString * a_prop, + CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_prop && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list && PRIVATE (list), NULL); + + PRIVATE (list)->prop = a_prop; + PRIVATE (list)->decl = a_decl; + + result = cr_prop_list_append (a_this, list); + return result; +} + +/** + * cr_prop_list_prepend: + *@a_this: the current instance of #CRPropList + *@a_to_prepend: the new list to prepend. + * + *Prepends a list to the current list + *Returns the new properties list. + */ +CRPropList * +cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_prepend, NULL); + + if (!a_this) + return a_to_prepend; + + for (cur = a_to_prepend; cur && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_this; + PRIVATE (a_this)->prev = cur; + return a_to_prepend; +} + +/** + * cr_prop_list_prepend2: + *@a_this: the current instance of #CRPropList + *@a_prop_name: property name to append + *@a_decl: the property value to append. + * + *Prepends a property to a list of properties + * + *Returns the new property list. + */ +CRPropList * +cr_prop_list_prepend2 (CRPropList * a_this, + CRString * a_prop_name, CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop_name && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list, NULL); + PRIVATE (list)->prop = a_prop_name; + PRIVATE (list)->decl = a_decl; + result = cr_prop_list_prepend (a_this, list); + return result; +} + +/** + * cr_prop_list_set_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: the property to set + * + *Sets the property of a CRPropList + */ +enum CRStatus +cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->prop = a_prop; + return CR_OK; +} + +/** + * cr_prop_list_get_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: out parameter. The returned property + * + *Getter of the property associated to the current instance + *of #CRPropList + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_prop_list_get_prop (CRPropList const * a_this, CRString ** a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + *a_prop = PRIVATE (a_this)->prop; + return CR_OK; +} + +/** + * cr_prop_list_set_decl: + * @a_this: the current instance of #CRPropList + * @a_decl: the new property value. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->decl = a_decl; + return CR_OK; +} + +/** + * cr_prop_list_get_decl: + * @a_this: the current instance of #CRPropList + * @a_decl: out parameter. The property value + * + * Returns CR_OK upon successful completion. + */ +enum CRStatus +cr_prop_list_get_decl (CRPropList const * a_this, CRDeclaration ** a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + *a_decl = PRIVATE (a_this)->decl; + return CR_OK; +} + +/** + * cr_prop_list_lookup_prop: + *@a_this: the current instance of #CRPropList + *@a_prop: the property to lookup + *@a_prop_list: out parameter. The property/declaration + *pair found (if and only if the function returned code if CR_OK) + * + *Lookup a given property/declaration pair + * + *Returns CR_OK if a prop/decl pair has been found, + *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something + *bad happens. + */ +enum CRStatus +cr_prop_list_lookup_prop (CRPropList * a_this, + CRString * a_prop, CRPropList ** a_pair) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR); + + if (!a_this) + return CR_VALUE_NOT_FOUND_ERROR; + + g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (cur = a_this; cur; cur = PRIVATE (cur)->next) { + if (PRIVATE (cur)->prop + && PRIVATE (cur)->prop->stryng + && PRIVATE (cur)->prop->stryng->str + && a_prop->stryng + && a_prop->stryng->str + && !strcmp (PRIVATE (cur)->prop->stryng->str, + a_prop->stryng->str)) + break; + } + + if (cur) { + *a_pair = cur; + return CR_OK; + } + + return CR_VALUE_NOT_FOUND_ERROR; +} + +/** + * cr_prop_list_get_next: + *@a_this: the current instance of CRPropList + * + *Gets the next prop/decl pair in the list + * + *Returns the next prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_next (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->next; +} + +/** + * cr_prop_list_get_prev: + *@a_this: the current instance of CRPropList + * + *Gets the previous prop/decl pair in the list + * + *Returns the previous prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_prev (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->prev; +} + +/** + * cr_prop_list_unlink: + *@a_this: the current list of prop/decl pairs + *@a_pair: the prop/decl pair to unlink. + * + *Unlinks a prop/decl pair from the list + * + *Returns the new list or NULL in case of an error. + */ +CRPropList * +cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair) +{ + CRPropList *prev = NULL, + *next = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL); + + /*some sanity checks */ + if (PRIVATE (a_pair)->next) { + next = PRIVATE (a_pair)->next; + g_return_val_if_fail (PRIVATE (next), NULL); + g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL); + } + if (PRIVATE (a_pair)->prev) { + prev = PRIVATE (a_pair)->prev; + g_return_val_if_fail (PRIVATE (prev), NULL); + g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL); + } + if (prev) { + PRIVATE (prev)->next = next; + } + if (next) { + PRIVATE (next)->prev = prev; + } + PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL; + if (a_this == a_pair) { + if (next) + return next; + return NULL; + } + return a_this; +} + +/** + * cr_prop_list_destroy: + * @a_this: the current instance of #CRPropList + */ +void +cr_prop_list_destroy (CRPropList * a_this) +{ + CRPropList *tail = NULL, + *cur = NULL; + + g_return_if_fail (a_this && PRIVATE (a_this)); + + for (tail = a_this; + tail && PRIVATE (tail) && PRIVATE (tail)->next; + tail = cr_prop_list_get_next (tail)) ; + g_return_if_fail (tail); + + cur = tail; + + while (cur) { + tail = PRIVATE (cur)->prev; + if (tail && PRIVATE (tail)) + PRIVATE (tail)->next = NULL; + PRIVATE (cur)->prev = NULL; + g_free (PRIVATE (cur)); + PRIVATE (cur) = NULL; + g_free (cur); + cur = tail; + } +} diff --git a/src/3rdparty/libcroco/src/cr-prop-list.h b/src/3rdparty/libcroco/src/cr-prop-list.h new file mode 100644 index 0000000..797ba43 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-prop-list.h @@ -0,0 +1,80 @@ +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_PROP_LIST_H__ +#define __CR_PROP_LIST_H__ + +#include "cr-utils.h" +#include "cr-declaration.h" +#include "cr-string.h" + +G_BEGIN_DECLS + +typedef struct _CRPropList CRPropList ; +typedef struct _CRPropListPriv CRPropListPriv ; + +struct _CRPropList +{ + CRPropListPriv * priv; +} ; + +CRPropList * cr_prop_list_append (CRPropList *a_this, + CRPropList *a_to_append) ; + +CRPropList * cr_prop_list_append2 (CRPropList *a_this, + CRString *a_prop, + CRDeclaration *a_decl) ; + +CRPropList * cr_prop_list_prepend (CRPropList *a_this, + CRPropList *a_to_append) ; + +CRPropList * cr_prop_list_prepend2 (CRPropList *a_this, + CRString *a_prop, + CRDeclaration *a_decl) ; + +enum CRStatus cr_prop_list_set_prop (CRPropList *a_this, + CRString *a_prop) ; + +enum CRStatus cr_prop_list_get_prop (CRPropList const *a_this, + CRString **a_prop) ; + +enum CRStatus cr_prop_list_lookup_prop (CRPropList *a_this, + CRString *a_prop, + CRPropList**a_pair) ; + +CRPropList * cr_prop_list_get_next (CRPropList *a_this) ; + +CRPropList * cr_prop_list_get_prev (CRPropList *a_this) ; + +enum CRStatus cr_prop_list_set_decl (CRPropList *a_this, + CRDeclaration *a_decl); + +enum CRStatus cr_prop_list_get_decl (CRPropList const *a_this, + CRDeclaration **a_decl) ; + +CRPropList * cr_prop_list_unlink (CRPropList *a_this, + CRPropList *a_pair) ; + +void cr_prop_list_destroy (CRPropList *a_this) ; + +G_END_DECLS + +#endif /*__CR_PROP_LIST_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-pseudo.c b/src/3rdparty/libcroco/src/cr-pseudo.c new file mode 100644 index 0000000..3644ab1 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-pseudo.c @@ -0,0 +1,166 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "cr-pseudo.h" + +/** + *@CRPseudo: + *The definition of the #CRPseudo class. + */ + +/** + * cr_pseudo_new: + *Constructor of the #CRPseudo class. + * + *Returns the newly build instance. + */ +CRPseudo * +cr_pseudo_new (void) +{ + CRPseudo *result = NULL; + + result = g_malloc0 (sizeof (CRPseudo)); + + return result; +} + +/** + * cr_pseudo_to_string: + * @a_this: the current instance of #CRPseud. + * + * Returns the serialized pseudo. Caller must free the returned + * string using g_free(). + */ +guchar * +cr_pseudo_to_string (CRPseudo const * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + if (a_this->type == IDENT_PSEUDO) { + gchar const *name = NULL; + + if (a_this->name == NULL) { + goto error; + } + + name = a_this->name->stryng->str; + + if (name) { + g_string_append (str_buf, (const gchar *) name); + name = NULL; + } + } else if (a_this->type == FUNCTION_PSEUDO) { + gchar const *name = NULL, + *arg = NULL; + + if (a_this->name == NULL) + goto error; + + name = a_this->name->stryng->str; + + if (a_this->term && a_this->term->type == TERM_IDENT) { + arg = a_this->term->content.str->stryng->str; + } + + if (name) { + g_string_append_printf (str_buf, "%s(", name); + name = NULL; + + if (arg) { + g_string_append (str_buf, (const gchar *) arg); + arg = NULL; + } + + g_string_append_c (str_buf, ')'); + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; + + error: + g_string_free (str_buf, TRUE); + return NULL; +} + +/** + * cr_pseudo_dump: + *@a_this: the current instance of pseudo + *@a_fp: the destination file pointer. + * + *Dumps the pseudo to a file. + * + */ +void +cr_pseudo_dump (CRPseudo const * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + if (a_this) { + tmp_str = cr_pseudo_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } +} + +/** + * cr_pseudo_destroy: + *@a_this: the current instance to destroy. + * + *destructor of the #CRPseudo class. + */ +void +cr_pseudo_destroy (CRPseudo * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->sel_name) { + cr_string_destroy (a_this->sel_name); + a_this->sel_name = NULL; + } + + if (a_this->term) { + cr_term_destroy (a_this->term); + a_this->term = NULL; + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-pseudo.h b/src/3rdparty/libcroco/src/cr-pseudo.h new file mode 100644 index 0000000..b784350 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-pseudo.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information + */ + +#ifndef __CR_PSEUDO_H__ +#define __CR_PSEUDO_H__ + +#include <stdio.h> +#include <glib.h> +#include "cr-attr-sel.h" +#include "cr-parsing-location.h" +#include "cr-term.h" + +G_BEGIN_DECLS + +enum CRPseudoType +{ + IDENT_PSEUDO = 0, + FUNCTION_PSEUDO +} ; + +typedef struct _CRPseudo CRPseudo ; + +/** + *The CRPseudo Class. + *Abstract a "pseudo" as defined by the css2 spec + *in appendix D.1 . + */ +struct _CRPseudo +{ + enum CRPseudoType type ; + CRString *name ; + CRString *sel_name; + CRTerm *term ; + CRParsingLocation location ; +} ; + +CRPseudo * cr_pseudo_new (void) ; + +guchar * cr_pseudo_to_string (CRPseudo const *a_this) ; + +void cr_pseudo_dump (CRPseudo const *a_this, FILE *a_fp) ; + +void cr_pseudo_destroy (CRPseudo *a_this) ; + +G_END_DECLS + +#endif /*__CR_PSEUDO_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-rgb.c b/src/3rdparty/libcroco/src/cr-rgb.c new file mode 100644 index 0000000..e2a1fc8 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-rgb.c @@ -0,0 +1,686 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "cr-rgb.h" +#include "cr-term.h" +#include "cr-parser.h" + +static const CRRgb gv_standard_colors[] = { + {(const guchar*)"aliceblue", 240, 248, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"antiquewhite", 250, 235, 215, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"aqua", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"aquamarine", 127, 255, 212, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"azure", 240, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"beige", 245, 245, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"bisque", 255, 228, 196, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"black", 0, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"blanchedalmond", 255, 235, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"blue", 0, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"blueviolet", 138, 43, 226, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"brown", 165, 42, 42, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"burlywood", 222, 184, 135, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"cadetblue", 95, 158, 160, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"chartreuse", 127, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"chocolate", 210, 105, 30, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"coral", 255, 127, 80, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"cornflowerblue", 100, 149, 237, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"cornsilk", 255, 248, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"crimson", 220, 20, 60, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"cyan", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkblue", 0, 0, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkcyan", 0, 139, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkgoldenrod", 184, 134, 11, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkgray", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkgreen", 0, 100, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkgrey", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkkhaki", 189, 183, 107, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkmagenta", 139, 0, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkolivegreen", 85, 107, 47, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkorange", 255, 140, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkorchid", 153, 50, 204, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkred", 139, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darksalmon", 233, 150, 122, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkseagreen", 143, 188, 143, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkslateblue", 72, 61, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkslategray", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkslategrey", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkturquoise", 0, 206, 209, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"darkviolet", 148, 0, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"deeppink", 255, 20, 147, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"deepskyblue", 0, 191, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"dimgray", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"dimgrey", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"dodgerblue", 30, 144, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"firebrick", 178, 34, 34, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"floralwhite", 255, 250, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"forestgreen", 34, 139, 34, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"fuchsia", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"gainsboro", 220, 220, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"ghostwhite", 248, 248, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"gold", 255, 215, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"goldenrod", 218, 165, 32, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"gray", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"green", 0, 128, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"greenyellow", 173, 255, 47, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"grey", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"honeydew", 240, 255, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"hotpink", 255, 105, 180, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"indianred", 205, 92, 92, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"indigo", 75, 0, 130, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"ivory", 255, 255, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"khaki", 240, 230, 140, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lavender", 230, 230, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lavenderblush", 255, 240, 245, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lawngreen", 124, 252, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lemonchiffon", 255, 250, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightblue", 173, 216, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightcoral", 240, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightcyan", 224, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightgoldenrodyellow", 250, 250, 210, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightgray", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightgreen", 144, 238, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightgrey", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightpink", 255, 182, 193, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightsalmon", 255, 160, 122, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightseagreen", 32, 178, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightskyblue", 135, 206, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightslategray", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightslategrey", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightsteelblue", 176, 196, 222, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lightyellow", 255, 255, 224, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"lime", 0, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"limegreen", 50, 205, 50, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"linen", 250, 240, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"magenta", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"maroon", 128, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumaquamarine", 102, 205, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumblue", 0, 0, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumorchid", 186, 85, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumpurple", 147, 112, 219, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumseagreen", 60, 179, 113, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumslateblue", 123, 104, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumspringgreen", 0, 250, 154, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumturquoise", 72, 209, 204, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mediumvioletred", 199, 21, 133, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"midnightblue", 25, 25, 112, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mintcream", 245, 255, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"mistyrose", 255, 228, 225, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"moccasin", 255, 228, 181, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"navajowhite", 255, 222, 173, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"navy", 0, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"oldlace", 253, 245, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"olive", 128, 128, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"olivedrab", 107, 142, 35, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"orange", 255, 165, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"orangered", 255, 69, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"orchid", 218, 112, 214, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"palegoldenrod", 238, 232, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"palegreen", 152, 251, 152, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"paleturquoise", 175, 238, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"palevioletred", 219, 112, 147, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"papayawhip", 255, 239, 213, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"peachpuff", 255, 218, 185, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"peru", 205, 133, 63, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"pink", 255, 192, 203, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"rebeccapurple", 102, 51, 153, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"saddlebrown", 139, 69, 19, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"salmon", 250, 128, 114, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"sandybrown", 244, 164, 96, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"seagreen", 46, 139, 87, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"seashell", 255, 245, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"sienna", 160, 82, 45, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"silver", 192, 192, 192, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"skyblue", 135, 206, 235, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"slateblue", 106, 90, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"slategray", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"slategrey", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"snow", 255, 250, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"springgreen", 0, 255, 127, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"steelblue", 70, 130, 180, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"tan", 210, 180, 140, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"teal", 0, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"thistle", 216, 191, 216, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"tomato", 255, 99, 71, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"transparent", 255, 255, 255, FALSE, FALSE, TRUE, {0,0,0}}, + {(const guchar*)"turquoise", 64, 224, 208, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"violet", 238, 130, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"wheat", 245, 222, 179, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"white", 255, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"whitesmoke", 245, 245, 245, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"yellow", 255, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"yellowgreen", 154, 205, 50, FALSE, FALSE, FALSE, {0,0,0}} +}; + +/** + * cr_rgb_new: + * + *The default constructor of #CRRgb. + * + *Returns the newly built instance of #CRRgb + */ +CRRgb * +cr_rgb_new (void) +{ + CRRgb *result = NULL; + + result = g_try_malloc (sizeof (CRRgb)); + + if (result == NULL) { + cr_utils_trace_info ("No more memory"); + return NULL; + } + + memset (result, 0, sizeof (CRRgb)); + + return result; +} + +/** + * cr_rgb_new_with_vals: + *@a_red: the red component of the color. + *@a_green: the green component of the color. + *@a_blue: the blue component of the color. + *@a_unit: the unit of the rgb values. + *(either percentage or integer values) + * + *A constructor of #CRRgb. + * + *Returns the newly built instance of #CRRgb. + */ +CRRgb * +cr_rgb_new_with_vals (gulong a_red, gulong a_green, + gulong a_blue, gboolean a_is_percentage) +{ + CRRgb *result = NULL; + + result = cr_rgb_new (); + + g_return_val_if_fail (result, NULL); + + result->red = a_red; + result->green = a_green; + result->blue = a_blue; + result->is_percentage = a_is_percentage; + + return result; +} + +/** + * cr_rgb_to_string: + *@a_this: the instance of #CRRgb to serialize. + * + *Serializes the rgb into a zero terminated string. + * + *Returns the zero terminated string containing the serialized + *rgb. MUST BE FREED by the caller using g_free(). + */ +guchar * +cr_rgb_to_string (CRRgb const * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if (a_this->is_percentage == 1) { + g_string_append_printf (str_buf, "%ld", a_this->red); + + g_string_append (str_buf, "%, "); + + g_string_append_printf (str_buf, "%ld", a_this->green); + g_string_append (str_buf, "%, "); + + g_string_append_printf (str_buf, "%ld", a_this->blue); + g_string_append_c (str_buf, '%'); + } else { + g_string_append_printf (str_buf, "%ld", a_this->red); + g_string_append (str_buf, ", "); + + g_string_append_printf (str_buf, "%ld", a_this->green); + g_string_append (str_buf, ", "); + + g_string_append_printf (str_buf, "%ld", a_this->blue); + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + } + + return result; +} + +/** + * cr_rgb_dump: + *@a_this: the "this pointer" of + *the current instance of #CRRgb. + *@a_fp: the destination file pointer. + * + *Dumps the current instance of #CRRgb + *to a file. + */ +void +cr_rgb_dump (CRRgb const * a_this, FILE * a_fp) +{ + guchar *str = NULL; + + g_return_if_fail (a_this); + + str = cr_rgb_to_string (a_this); + + if (str) { + fprintf (a_fp, "%s", str); + g_free (str); + str = NULL; + } +} + +/** + * cr_rgb_compute_from_percentage: + *@a_this: the current instance of #CRRgb + * + *If the rgb values are expressed in percentage, + *compute their real value. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_compute_from_percentage (CRRgb * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + if (a_this->is_percentage == FALSE) + return CR_OK; + a_this->red = a_this->red * 255 / 100; + a_this->green = a_this->green * 255 / 100; + a_this->blue = a_this->blue * 255 / 100; + a_this->is_percentage = FALSE; + return CR_OK; +} + +/** + * cr_rgb_set: + *@a_this: the current instance of #CRRgb. + *@a_red: the red value. + *@a_green: the green value. + *@a_blue: the blue value. + * + *Sets rgb values to the RGB. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_rgb_set (CRRgb * a_this, gulong a_red, + gulong a_green, gulong a_blue, gboolean a_is_percentage) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + if (a_is_percentage != FALSE) { + g_return_val_if_fail (a_red <= 100 + && a_green <= 100 + && a_blue <= 100, CR_BAD_PARAM_ERROR); + } + + a_this->is_percentage = a_is_percentage; + + a_this->red = a_red; + a_this->green = a_green; + a_this->blue = a_blue; + a_this->inherit = FALSE ; + a_this->is_transparent = FALSE ; + return CR_OK; +} + +/** + * cr_rgb_set_to_inherit: + *@a_this: the current instance of #CRRgb + * + *sets the value of the rgb to inherit. + *Look at the css spec from chapter 6.1 to 6.2 to understand + *the meaning of "inherit". + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + a_this->inherit = a_inherit ; + + return CR_OK ; +} + +/** + * cr_rgb_is_set_to_inherit: + * + * @a_this: the current instance of #CRRgb. + * + * Returns TRUE if the rgb is set to the value "inherit", FALSE otherwise. + */ +gboolean +cr_rgb_is_set_to_inherit (CRRgb const *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + return a_this->inherit ; +} + +/** + * cr_rgb_is_set_to_transparent: + *@a_this: the current instance of + *#CRRgb + * + *Tests if the rgb is set to the + *value "transparent" or not. + * + *Returns TRUE if the rgb has been set to + *transparent, FALSE otherwise. + */ +gboolean +cr_rgb_is_set_to_transparent (CRRgb const *a_this) +{ + g_return_val_if_fail (a_this, FALSE) ; + return a_this->is_transparent ; +} + + +/** + * cr_rgb_set_to_transparent: + *@a_this: the current instance of #CRRgb + *@a_is_transparent: set to transparent or not. + * + *Sets the rgb to the "transparent" value (or not) + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_to_transparent (CRRgb *a_this, + gboolean a_is_transparent) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + a_this->is_transparent = a_is_transparent ; + return CR_OK ; +} + +/** + * cr_rgb_set_from_rgb: + *@a_this: the current instance of #CRRgb. + *@a_rgb: the rgb to "copy" + * + *Sets the rgb from an other one. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb const * a_rgb) +{ + g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR); + + cr_rgb_copy (a_this, a_rgb) ; + + return CR_OK; +} + +static int +cr_rgb_color_name_compare (const void *a, + const void *b) +{ + const char *a_color_name = a; + const CRRgb *rgb = b; + + return g_ascii_strcasecmp (a_color_name, (const char *) rgb->name); +} + +/** + * cr_rgb_set_from_name: + * @a_this: the current instance of #CRRgb + * @a_color_name: the color name + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name) +{ + enum CRStatus status = CR_OK; + CRRgb *result; + + g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR); + + result = bsearch (a_color_name, + gv_standard_colors, + G_N_ELEMENTS (gv_standard_colors), + sizeof (gv_standard_colors[0]), + cr_rgb_color_name_compare); + if (result != NULL) + cr_rgb_set_from_rgb (a_this, result); + else + status = CR_UNKNOWN_TYPE_ERROR; + + return status; +} + +/** + * cr_rgb_set_from_hex_str: + * @a_this: the current instance of #CRRgb + * @a_hex: the hexadecimal value to set. + * + * Returns CR_OK upon successful completion. + */ +enum CRStatus +cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex) +{ + enum CRStatus status = CR_OK; + gulong i = 0; + guchar colors[3] = { 0 }; + + g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR); + + if (strlen ((const char *) a_hex) == 3) { + for (i = 0; i < 3; i++) { + if (a_hex[i] >= '0' && a_hex[i] <= '9') { + colors[i] = a_hex[i] - '0'; + colors[i] = (colors[i] << 4) | colors[i]; + } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') { + colors[i] = 10 + a_hex[i] - 'a'; + colors[i] = (colors[i] << 4) | colors[i]; + } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') { + colors[i] = 10 + a_hex[i] - 'A'; + colors[i] = (colors[i] << 4) | colors[i]; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + } + } else if (strlen ((const char *) a_hex) == 6) { + for (i = 0; i < 6; i++) { + if (a_hex[i] >= '0' && a_hex[i] <= '9') { + colors[i / 2] <<= 4; + colors[i / 2] |= a_hex[i] - '0'; + status = CR_OK; + } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') { + colors[i / 2] <<= 4; + colors[i / 2] |= 10 + a_hex[i] - 'a'; + status = CR_OK; + } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') { + colors[i / 2] <<= 4; + colors[i / 2] |= 10 + a_hex[i] - 'A'; + status = CR_OK; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + } + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + + if (status == CR_OK) { + status = cr_rgb_set (a_this, colors[0], + colors[1], colors[2], FALSE); + cr_rgb_set_to_transparent (a_this, FALSE) ; + } + return status; +} + +/** + * cr_rgb_set_from_term: + *@a_this: the instance of #CRRgb to set + *@a_value: the terminal from which to set + * + *Set the rgb from a terminal symbol + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value) +{ + enum CRStatus status = CR_OK ; + g_return_val_if_fail (a_this && a_value, + CR_BAD_PARAM_ERROR) ; + + switch(a_value->type) { + case TERM_RGB: + if (a_value->content.rgb) { + cr_rgb_set_from_rgb + (a_this, a_value->content.rgb) ; + } + break ; + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + a_this->inherit = TRUE; + a_this->is_transparent = FALSE ; + } else { + status = cr_rgb_set_from_name + (a_this, + (const guchar *) a_value->content.str->stryng->str) ; + } + } else { + cr_utils_trace_info + ("a_value has NULL string value") ; + } + break ; + case TERM_HASH: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + status = cr_rgb_set_from_hex_str + (a_this, + (const guchar *) a_value->content.str->stryng->str) ; + } else { + cr_utils_trace_info + ("a_value has NULL string value") ; + } + break ; + default: + status = CR_UNKNOWN_TYPE_ERROR ; + } + return status ; +} + +enum CRStatus +cr_rgb_copy (CRRgb *a_dest, CRRgb const *a_src) +{ + g_return_val_if_fail (a_dest && a_src, + CR_BAD_PARAM_ERROR) ; + + memcpy (a_dest, a_src, sizeof (CRRgb)) ; + return CR_OK ; +} + +/** + * cr_rgb_destroy: + *@a_this: the "this pointer" of the + *current instance of #CRRgb. + * + *Destructor of #CRRgb. + */ +void +cr_rgb_destroy (CRRgb * a_this) +{ + g_return_if_fail (a_this); + g_free (a_this); +} + +/** + * cr_rgb_parse_from_buf: + *@a_str: a string that contains a color description + *@a_enc: the encoding of a_str + * + *Parses a text buffer that contains a rgb color + * + *Returns the parsed color, or NULL in case of error + */ +CRRgb * +cr_rgb_parse_from_buf (const guchar *a_str, + enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK ; + CRTerm *value = NULL ; + CRParser * parser = NULL; + CRRgb *result = NULL; + + g_return_val_if_fail (a_str, NULL); + + parser = cr_parser_new_from_buf ((guchar *) a_str, strlen ((const char *) a_str), a_enc, FALSE); + + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser) ; + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_term (parser, &value); + if (status != CR_OK) + goto cleanup; + + result = cr_rgb_new (); + if (!result) + goto cleanup; + + status = cr_rgb_set_from_term (result, value); + +cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (value) { + cr_term_destroy(value); + value = NULL; + } + return result ; +} + diff --git a/src/3rdparty/libcroco/src/cr-rgb.h b/src/3rdparty/libcroco/src/cr-rgb.h new file mode 100644 index 0000000..a127a44 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-rgb.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * see COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_RGB_H__ +#define __CR_RGB_H__ + +#include <stdio.h> +#include <glib.h> +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + + +typedef struct _CRRgb CRRgb ; +struct _CRRgb +{ + /* + *the unit of the rgb. + *Either NO_UNIT (integer) or + *UNIT_PERCENTAGE (percentage). + */ + const guchar *name ; + glong red ; + glong green ; + glong blue ; + gboolean is_percentage ; + gboolean inherit ; + gboolean is_transparent ; + CRParsingLocation location ; +} ; + +CRRgb * cr_rgb_new (void) ; + +CRRgb * cr_rgb_new_with_vals (gulong a_red, gulong a_green, + gulong a_blue, gboolean a_is_percentage) ; + +CRRgb *cr_rgb_parse_from_buf(const guchar *a_str, + enum CREncoding a_enc); + +enum CRStatus cr_rgb_compute_from_percentage (CRRgb *a_this) ; + +enum CRStatus cr_rgb_set (CRRgb *a_this, gulong a_red, + gulong a_green, gulong a_blue, + gboolean a_is_percentage) ; + +enum CRStatus cr_rgb_copy (CRRgb *a_dest, CRRgb const *a_src) ; + +enum CRStatus cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit) ; + +gboolean cr_rgb_is_set_to_inherit (CRRgb const *a_this) ; + +gboolean cr_rgb_is_set_to_transparent (CRRgb const *a_this) ; + +enum CRStatus cr_rgb_set_to_transparent (CRRgb *a_this, + gboolean a_is_transparent) ; +enum CRStatus cr_rgb_set_from_rgb (CRRgb *a_this, CRRgb const *a_rgb) ; + +enum CRStatus cr_rgb_set_from_name (CRRgb *a_this, const guchar *a_color_name) ; + +enum CRStatus cr_rgb_set_from_hex_str (CRRgb *a_this, const guchar * a_hex_value) ; + +struct _CRTerm; + +enum CRStatus cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value); + +guchar * cr_rgb_to_string (CRRgb const *a_this) ; + +void cr_rgb_dump (CRRgb const *a_this, FILE *a_fp) ; + +void cr_rgb_destroy (CRRgb *a_this) ; + +G_END_DECLS + +#endif /*__CR_RGB_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-sel-eng.c b/src/3rdparty/libcroco/src/cr-sel-eng.c new file mode 100644 index 0000000..8ed485d --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-sel-eng.c @@ -0,0 +1,2236 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser + * General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-sel-eng.h" +#include "cr-node-iface.h" + +/** + *@CRSelEng: + * + *The definition of the #CRSelEng class. + *The #CRSelEng is actually the "Selection Engine" + *class. This is highly experimental for at the moment and + *its api is very likely to change in a near future. + */ + +#define PRIVATE(a_this) (a_this)->priv + +struct CRPseudoClassSelHandlerEntry { + guchar *name; + enum CRPseudoType type; + CRPseudoClassSelectorHandler handler; +}; + +struct _CRSelEngPriv { + /*not used yet */ + gboolean case_sensitive; + + CRNodeIface const *node_iface; + CRStyleSheet *sheet; + /** + *where to store the next statement + *to be visited so that we can remember + *it from one method call to another. + */ + CRStatement *cur_stmt; + GList *pcs_handlers; + gint pcs_handlers_size; +} ; + +static gboolean class_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static gboolean id_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static gboolean attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static enum CRStatus sel_matches_node_real (CRSelEng * a_this, + CRSimpleSel * a_sel, + CRXMLNodePtr a_node, + gboolean * a_result, + gboolean a_eval_sel_list_from_end, + gboolean a_recurse); + +static enum CRStatus cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this, + CRStyleSheet * + a_stylesheet, + CRXMLNodePtr a_node, + CRStatement *** + a_rulesets, + gulong * a_len, + gulong * a_capacity); + +static enum CRStatus put_css_properties_in_props_list (CRPropList ** a_props, + CRStatement * + a_ruleset); + +static gboolean pseudo_class_add_sel_matches_node (CRSelEng * a_this, + CRAdditionalSel * a_add_sel, + CRXMLNodePtr a_node); + +static gboolean empty_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean root_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean lang_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean only_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean first_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean first_of_type_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean last_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean last_of_type_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean nth_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean nth_of_type_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean nth_last_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean nth_last_of_type_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static CRXMLNodePtr get_next_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_first_child_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_prev_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_next_parent_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRArguments get_arguments_from_function (CRAdditionalSel * a_sel); + +void +cr_sel_eng_set_node_iface (CRSelEng *const a_this, CRNodeIface const *const a_node_iface) +{ + /* Allow NULL: the caller may be just ensuring that the previous node_iface + value doesn't get used until next cr_sel_eng_set_node_iface call. */ + PRIVATE(a_this)->node_iface = a_node_iface; +} + +/* Quick strcmp. Test only for == 0 or != 0, not < 0 or > 0. */ +#define strqcmp(str,lit,lit_len) \ + (strlen (str) != (lit_len) || memcmp (str, lit, lit_len)) + +static gboolean +root_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "root") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :root only"); + return FALSE; + } + + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + + // libxml apears to set the parent of the root element to an + // element of type 'xml'. + return (parent == NULL || !strcmp(node_iface->getLocalName(parent),"xml") ); +} + +static gboolean +empty_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr cur_node = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "empty") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :empty only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + + cur_node = node_iface->getFirstChild (a_node); + + return (cur_node == NULL); +} + +static gboolean +lang_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr a_node) +{ + CRNodeIface const *node_iface; + CRXMLNodePtr node = a_node; + gboolean result = FALSE; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + node_iface = PRIVATE(a_this)->node_iface; + + /* "xml:lang" needed for SVG */ + if ( (strqcmp (a_sel->content.pseudo->name->stryng->str, "lang", 4 ) && + (strqcmp (a_sel->content.pseudo->name->stryng->str, "xml:lang", 8 ) ) ) + || a_sel->content.pseudo->type != FUNCTION_PSEUDO) { + cr_utils_trace_info ("This handler is for :lang only"); + return FALSE; + } + /*lang code should exist and be at least of length 2 */ + if (!a_sel->content.pseudo->term + || a_sel->content.pseudo->term->type != TERM_IDENT + || !a_sel->content.pseudo->term->content.str->stryng + || a_sel->content.pseudo->term->content.str->stryng->len < 2) + return FALSE; + for (; node; node = get_next_parent_element_node (node_iface, node)) { + char *val = node_iface->getProp (node, "lang"); + if (!val) val = node_iface->getProp (node, "xml:lang"); + if (val) { + if (!strcasecmp(val, a_sel->content.pseudo->term->content.str->stryng->str)) { + result = TRUE; + break; + } + node_iface->freePropVal (val); + val = NULL; + } + } + + return result; +} + +static gboolean +only_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + CRXMLNodePtr cur_node = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "only-child") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :only-child only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + return (cur_node == a_node && + !get_next_element_node(node_iface, cur_node) ); +} + +static gboolean +only_of_type_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + CRXMLNodePtr cur_node = NULL; + int m = 0; + int child = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "only-of-type") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :only-of-type selector only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + if (!strcmp(node_iface->getLocalName(cur_node), a_sel->content.pseudo->sel_name->stryng->str)) { + ++m; + } + if (cur_node == a_node) { + child = m; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + return (child == m && child == 1); +} + +static gboolean +first_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr node = NULL; + CRXMLNodePtr parent = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "first-child") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :first-child only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + node = get_first_child_element_node (node_iface, parent); + return (node == a_node); +} + +static gboolean +first_of_type_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + // Count which child no. of type + CRXMLNodePtr cur_node = NULL; + int child = 0; + int found = FALSE; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "first-of-type") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :first-of-type only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + if(!strcmp(node_iface->getLocalName(cur_node), a_sel->content.pseudo->sel_name->stryng->str)) { + child++; + } + if (cur_node == a_node) { + found = TRUE; + break; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + + if (!found) + return FALSE; + + return (child == 1); +} + +static gboolean +last_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + CRXMLNodePtr cur_node = NULL; + int m = 0; + int child = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "last-child") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :last-child only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + while (cur_node) { + ++m; + if (cur_node == a_node) { + child = m; + } + cur_node = get_next_element_node (node_iface, cur_node); + + } + return (m == child); +} + +static gboolean +last_of_type_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + CRXMLNodePtr cur_node = NULL; + int m = 0; + int child = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "last-of-type") + || a_sel->content.pseudo->type != IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :last-of-type only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + if (!strcmp(node_iface->getLocalName(cur_node), a_sel->content.pseudo->sel_name->stryng->str)) { + ++m; + } + if (cur_node == a_node) { + child = m; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + + return (m == child); +} + +// See https://www.w3.org/TR/selectors/#nth-child-pseudo +static gboolean +nth_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + /* Count which child this is */ + CRXMLNodePtr cur_node = NULL; + int child = 0; + int found = FALSE; + int a, b; + CRArguments arg; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "nth-child") + || a_sel->content.pseudo->type != FUNCTION_PSEUDO) { + cr_utils_trace_info ("This handler is for :nth-child only"); + return FALSE; + } + + /*pseude code term should exist */ + if (!a_sel->content.pseudo->term) + return FALSE; + + arg = get_arguments_from_function (a_sel); + + if (arg.a == 0 && arg.b == 0) + return FALSE; + + a = arg.a; + b = arg.b; + + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + ++child; + if (cur_node == a_node) { + found = TRUE; + break; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + + if (!found) + return FALSE; + + if (a == 0) + return (b == child); + + return ((child - b)%a == 0 && (child - b)/a > -1); +} + +static gboolean +nth_of_type_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + // Count which child no. of required type + CRXMLNodePtr cur_node = NULL; + int child = 0; + int found = FALSE; + int a, b; + CRArguments arg; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "nth-of-type") + || a_sel->content.pseudo->type != FUNCTION_PSEUDO) { + cr_utils_trace_info ("This handler is for :nth-of-type only"); + return FALSE; + } + + // pseudo code term should exist + if (!a_sel->content.pseudo->term) + return FALSE; + + arg = get_arguments_from_function (a_sel); + + if (arg.a == 0 && arg.b == 0) + return FALSE; + + a = arg.a; + b = arg.b; + + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + // check if type match + if (!strcmp(node_iface->getLocalName(cur_node), a_sel->content.pseudo->sel_name->stryng->str)) + ++child; + if (cur_node == a_node) { + found = TRUE; + break; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + + if (!found) + return FALSE; + + if (a == 0) + return (b == child); + + return ((child - b)%a == 0 && (child - b)/a > -1); +} + +static gboolean +nth_last_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + + /* Count which child this is (child) and total number of children (m). */ + CRXMLNodePtr cur_node = NULL; + int m = 0; + int child = 0; + int found = FALSE; + int a, b; + CRArguments arg; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "nth-last-child")) { + cr_utils_trace_info ("This handler is for :nth-last-child only"); + return FALSE; + } + + /*pseudo code term should exist */ + if (!a_sel->content.pseudo->term) + return FALSE; + + arg = get_arguments_from_function (a_sel); + + if (arg.a == 0 && arg.b == 0) + return FALSE; + + a = arg.a; + b = arg.b; + + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + + if (!parent) { + return FALSE; + } + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + if (cur_node == a_node) { + found = TRUE; + child = m; + } + cur_node = get_next_element_node (node_iface,cur_node); + ++m; + } + + if (!found) + return FALSE; + + if (a == 0) + return ((m - b) == child); + + return ((m - child - b)%a == 0 && (m - child - b)/a > -1); +} + +static gboolean +nth_last_of_type_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr parent = NULL; + CRXMLNodePtr cur_node = NULL; + int m = 0; + int child = 0; + int found = FALSE; + CRArguments arg; + int a, b; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, "nth-last-of-type")) { + cr_utils_trace_info ("This handler is for :nth-last-of-type only"); + return FALSE; + } + + /*pseude code term should exist */ + if (!a_sel->content.pseudo->term) + return FALSE; + + arg = get_arguments_from_function (a_sel); + + if (arg.a == 0 && arg.b == 0) + return FALSE; + + a = arg.a; + b = arg.b; + + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) { + return FALSE; + } + + cur_node = get_first_child_element_node (node_iface, parent); + + while (cur_node) { + if (!strcmp(node_iface->getLocalName(cur_node), a_sel->content.pseudo->sel_name->stryng->str)) + ++m; + if (cur_node == a_node) { + found = TRUE; + child = m; + } + cur_node = get_next_element_node (node_iface, cur_node); + } + + if (!found) + return FALSE; + + if (a == 0) + return ((m - b) == child); + + return ((m - child - b +1)%a == 0 && (m - child - b +1)/a > -1); + +} + +static gboolean +pseudo_class_add_sel_matches_node (CRSelEng * a_this, + CRAdditionalSel * a_add_sel, + CRXMLNodePtr a_node) +{ + enum CRStatus status = CR_OK; + CRPseudoClassSelectorHandler handler = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_add_sel + && a_add_sel->content.pseudo + && a_add_sel->content.pseudo->name + && a_add_sel->content.pseudo->name->stryng + && a_add_sel->content.pseudo->name->stryng->str + && a_node, FALSE); + + status = cr_sel_eng_get_pseudo_class_selector_handler + (a_this, (guchar *) a_add_sel->content.pseudo->name->stryng->str, + a_add_sel->content.pseudo->type, &handler); + if (status != CR_OK || !handler) + return FALSE; + + return handler (a_this, a_add_sel, a_node); +} + +/** + *@param a_add_sel the class additional selector to consider. + *@param a_node the xml node to consider. + *@return TRUE if the class additional selector matches + *the xml node given in argument, FALSE otherwise. + */ +static gboolean +class_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + gboolean result = FALSE; + char *klass = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == CLASS_ADD_SELECTOR + && a_add_sel->content.class_name + && a_add_sel->content.class_name->stryng + && a_add_sel->content.class_name->stryng->str + && a_node, FALSE); + + klass = a_node_iface->getProp (a_node, "class"); + if (klass) { + char const *cur; + for (cur = klass; cur && *cur; cur++) { + while (cur && *cur + && cr_utils_is_white_space (*cur) + == TRUE) + cur++; + + if (!strncmp ((const char *) cur, + a_add_sel->content.class_name->stryng->str, + a_add_sel->content.class_name->stryng->len)) { + cur += a_add_sel->content.class_name->stryng->len; + if ((cur && !*cur) + || cr_utils_is_white_space (*cur) == TRUE) + result = TRUE; + } else { /* if it doesn't match, */ + /* then skip to next whitespace character to try again */ + while (cur && *cur && !(cr_utils_is_white_space(*cur) == TRUE)) + cur++; + } + if (cur && !*cur) + break ; + } + a_node_iface->freePropVal (klass); + klass = NULL; + } + return result; + +} + +/** + *@return TRUE if the additional attribute selector matches + *the current xml node given in argument, FALSE otherwise. + *@param a_add_sel the additional attribute selector to consider. + *@param a_node the xml node to consider. + */ +static gboolean +id_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + gboolean result = FALSE; + char *id = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ID_ADD_SELECTOR + && a_add_sel->content.id_name + && a_add_sel->content.id_name->stryng + && a_add_sel->content.id_name->stryng->str + && a_node, FALSE); + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ID_ADD_SELECTOR + && a_node, FALSE); + + id = a_node_iface->getProp (a_node, "id"); + if (id) { + if (!strqcmp ((const char *) id, a_add_sel->content.id_name->stryng->str, + a_add_sel->content.id_name->stryng->len)) { + result = TRUE; + } + a_node_iface->freePropVal (id); + id = NULL; + } + return result; +} + +/** + *Returns TRUE if the instance of #CRAdditional selector matches + *the node given in parameter, FALSE otherwise. + *@param a_add_sel the additional selector to evaluate. + *@param a_node the xml node against which the selector is to + *be evaluated + *return TRUE if the additional selector matches the current xml node + *FALSE otherwise. + */ +static gboolean +attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRAttrSel *cur_sel = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ATTRIBUTE_ADD_SELECTOR + && a_node, FALSE); + + for (cur_sel = a_add_sel->content.attr_sel; + cur_sel; cur_sel = cur_sel->next) { + char *value; + + if (!cur_sel->name + || !cur_sel->name->stryng + || !cur_sel->name->stryng->str) + return FALSE; + + value = a_node_iface->getProp (a_node, cur_sel->name->stryng->str); + if (!value) + goto free_and_return_false; + + switch (cur_sel->match_way) { + case SET: + break; + + case EQUALS: + if (!cur_sel->value + || !cur_sel->value->stryng + || !cur_sel->value->stryng->str) { + goto free_and_return_false; + } + if (strcmp + (value, + cur_sel->value->stryng->str)) { + goto free_and_return_false; + } + break; + + case INCLUDES: + { + char const *ptr1 = NULL, + *ptr2 = NULL, + *cur = NULL; + gboolean found = FALSE; + + /* + *here, make sure value is a space + *separated list of "words", where one + *value is exactly cur_sel->value->str + */ + for (cur = value; *cur; cur++) { + /* + *set ptr1 to the first non white space + *char addr. + */ + while (cr_utils_is_white_space (*cur) + && *cur) + cur++; + if (!*cur) + break; + ptr1 = cur; + + /* + *set ptr2 to the end the word. + */ + while (!cr_utils_is_white_space (*cur) + && *cur) + cur++; + cur--; + ptr2 = cur; + + if (!strncmp + ((const char *) ptr1, + cur_sel->value->stryng->str, + ptr2 - ptr1 + 1)) { + found = TRUE; + break; + } + ptr1 = ptr2 = NULL; + } + + if (!found) { + goto free_and_return_false; + } + } + break; + + case DASHMATCH: + { + char const *ptr1 = NULL, + *ptr2 = NULL, + *cur = NULL; + gboolean found = FALSE; + + /* + *here, make sure value is an hyphen + *separated list of "words", each of which + *starting with "cur_sel->value->str" + */ + for (cur = value; *cur; cur++) { + if (*cur == '-') + cur++; + ptr1 = cur; + + while (*cur != '-' && *cur) + cur++; + cur--; + ptr2 = cur; + + if (g_strstr_len + ((const gchar *) ptr1, ptr2 - ptr1 + 1, + cur_sel->value->stryng->str) + == ptr1) { + found = TRUE; + break; + } + } + + if (!found) { + goto free_and_return_false; + } + } + break; + default: + goto free_and_return_false; + } + + a_node_iface->freePropVal (value); + continue; + + free_and_return_false: + a_node_iface->freePropVal (value); + return FALSE; + } + + return TRUE; +} + +/** + *Evaluates if a given additional selector matches an xml node. + *@param a_add_sel the additional selector to consider. + *@param a_node the xml node to consider. + *@return TRUE is a_add_sel matches a_node, FALSE otherwise. + */ +static gboolean +additional_selector_matches_node (CRSelEng * a_this, + CRAdditionalSel * a_add_sel, + CRXMLNodePtr a_node) +{ + CRAdditionalSel *cur_add_sel = NULL, *tail = NULL ; + gboolean evaluated = FALSE ; + + for (tail = a_add_sel ; + tail && tail->next; + tail = tail->next) ; + + g_return_val_if_fail (tail, FALSE) ; + + for (cur_add_sel = tail ; + cur_add_sel ; + cur_add_sel = cur_add_sel->prev) { + + evaluated = TRUE ; + if (cur_add_sel->type == NO_ADD_SELECTOR) { + return FALSE; + } + + if (cur_add_sel->type == CLASS_ADD_SELECTOR + && cur_add_sel->content.class_name + && cur_add_sel->content.class_name->stryng + && cur_add_sel->content.class_name->stryng->str) { + if (!class_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == ID_ADD_SELECTOR + && cur_add_sel->content.id_name + && cur_add_sel->content.id_name->stryng + && cur_add_sel->content.id_name->stryng->str) { + if (!id_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == ATTRIBUTE_ADD_SELECTOR + && cur_add_sel->content.attr_sel) { + /* + *here, call a function that does the match + *against an attribute additional selector + *and an xml node. + */ + if (!attr_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == PSEUDO_CLASS_ADD_SELECTOR + && cur_add_sel->content.pseudo) { + if (!pseudo_class_add_sel_matches_node + (a_this, cur_add_sel, a_node)) { + return FALSE; + } + continue ; + } + } + if (evaluated == TRUE) + return TRUE; + return FALSE ; +} + +static CRXMLNodePtr +get_next_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getNextSibling (cur_node); + } while (cur_node && !a_node_iface->isElementNode(cur_node)); + return cur_node; +} + +static CRXMLNodePtr +get_first_child_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = NULL; + + g_return_val_if_fail (a_node, NULL); + + cur_node = a_node_iface->getFirstChild (a_node); + if (!cur_node) + return cur_node; + if (a_node_iface->isElementNode (cur_node)) + return cur_node; + return get_next_element_node (a_node_iface, cur_node); +} + +static CRXMLNodePtr +get_prev_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getPrevSibling (cur_node); + } while (cur_node && !a_node_iface->isElementNode(cur_node)); + return cur_node; +} + +static CRXMLNodePtr +get_next_parent_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getParentNode (cur_node); + } while (cur_node && !a_node_iface->isElementNode (cur_node)); + return cur_node; +} + +static CRArguments +get_arguments_from_function (CRAdditionalSel * a_sel) +{ + CRArguments arg; + arg.a = 0; + arg.b = 0; + switch (a_sel->content.pseudo->term->type) { + case TERM_NUMBER: + if (a_sel->content.pseudo->term->content.num) { + arg.b = a_sel->content.pseudo->term->content.num->val; + } + if (a_sel->content.pseudo->term->n) { + arg.a = arg.b; + arg.b = 0; + } + break; + + case TERM_IDENT: + if (a_sel->content.pseudo->term->content.str) { + if (!strcmp(a_sel->content.pseudo->term->content.str->stryng->str, "even")) { + arg.a = 2; + arg.b = 0; + } else if (!strcmp(a_sel->content.pseudo->term->content.str->stryng->str, "odd")) { + arg.a = 2; + arg.b = 1; + } else if (!strcmp(a_sel->content.pseudo->term->content.str->stryng->str, "n")) { + /* 'n' without number */ + arg.a = 1; + } else if (!strcmp(a_sel->content.pseudo->term->content.str->stryng->str, "-n")) { + /* '-n' without number */ + arg.a = -1; + } else { + /* Unknown string */ + arg.a = 0; + arg.b = 0; + return (arg); + } + } + break; + + default: + cr_utils_trace_info ("Unknown term in nth style handler"); + arg.a = 0; + arg.b = 0; + return (arg); + } + + if (arg.a != 0 && a_sel->content.pseudo->term->next) { + /* check for b in 'an+b' */ + if (a_sel->content.pseudo->term->next->type == TERM_NUMBER && + a_sel->content.pseudo->term->next->content.num ) { + arg.b = a_sel->content.pseudo->term->next->content.num->val; + } + } + + return (arg); +} + +/** + *Evaluate a selector (a simple selectors list) and says + *if it matches the xml node given in parameter. + *The algorithm used here is the following: + *Walk the combinator separated list of simple selectors backward, starting + *from the end of the list. For each simple selector, looks if + *if matches the current node. + * + *@param a_this the selection engine. + *@param a_sel the simple selection list. + *@param a_node the xml node. + *@param a_result out parameter. Set to true if the + *selector matches the xml node, FALSE otherwise. + *@param a_recurse if set to TRUE, the function will walk to + *the next simple selector (after the evaluation of the current one) + *and recursively evaluate it. Must be usually set to TRUE unless you + *know what you are doing. + */ +static enum CRStatus +sel_matches_node_real (CRSelEng * a_this, CRSimpleSel * a_sel, + CRXMLNodePtr a_node, gboolean * a_result, + gboolean a_eval_sel_list_from_end, + gboolean a_recurse) +{ + CRSimpleSel *cur_sel = NULL; + CRXMLNodePtr cur_node = NULL; + CRNodeIface const *node_iface = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_this && a_node + && a_result, CR_BAD_PARAM_ERROR); + + node_iface = PRIVATE(a_this)->node_iface; + *a_result = FALSE; + + if (!node_iface->isElementNode(a_node)) + return CR_OK; + + if (a_eval_sel_list_from_end == TRUE) { + /*go and get the last simple selector of the list */ + for (cur_sel = a_sel; + cur_sel && cur_sel->next; cur_sel = cur_sel->next) ; + } else { + cur_sel = a_sel; + } + + for (cur_node = a_node; cur_sel; cur_sel = cur_sel->prev) { + if (((cur_sel->type_mask & TYPE_SELECTOR) + && (cur_sel->name + && cur_sel->name->stryng + && cur_sel->name->stryng->str) + && (!strcmp (cur_sel->name->stryng->str, + (const char *) node_iface->getLocalName(cur_node)))) + || (cur_sel->type_mask & UNIVERSAL_SELECTOR)) { + /* + *this simple selector + *matches the current xml node + *Let's see if the preceding + *simple selectors also match + *their xml node counterpart. + */ + if (cur_sel->add_sel) { + if (additional_selector_matches_node (a_this, cur_sel->add_sel, + cur_node) == TRUE) { + goto walk_a_step_in_expr; + } else { + goto done; + } + } else { + goto walk_a_step_in_expr; + } + } + if (!(cur_sel->type_mask & TYPE_SELECTOR) + && !(cur_sel->type_mask & UNIVERSAL_SELECTOR)) { + if (!cur_sel->add_sel) { + goto done; + } + if (additional_selector_matches_node + (a_this, cur_sel->add_sel, cur_node) + == TRUE) { + goto walk_a_step_in_expr; + } else { + goto done; + } + } else { + goto done ; + } + + walk_a_step_in_expr: + if (a_recurse == FALSE) { + *a_result = TRUE; + goto done; + } + + /* + *here, depending on the combinator of cur_sel + *choose the axis of the xml tree traversal + *and walk one step in the xml tree. + */ + if (!cur_sel->prev) + break; + + switch (cur_sel->combinator) { + case NO_COMBINATOR: + break; + + case COMB_WS: /*descendant selector */ + { + CRXMLNodePtr n = NULL; + enum CRStatus status = CR_OK; + gboolean matches = FALSE; + + /* + *walk the xml tree upward looking for a parent + *node that matches the preceding selector. + */ + for (n = node_iface->getParentNode (cur_node); + n; + n = node_iface->getParentNode (n)) { + status = sel_matches_node_real + (a_this, cur_sel->prev, + n, &matches, FALSE, TRUE); + + if (status != CR_OK) + goto done; + + if (matches == TRUE) { + cur_node = n ; + break; + } + } + + if (!n) { + /* + *didn't find any ancestor that matches + *the previous simple selector. + */ + goto done; + } + /* + *in this case, the preceding simple sel + *will have been interpreted twice, which + *is a cpu and mem waste ... I need to find + *another way to do this. Anyway, this is + *my first attempt to write this function and + *I am a bit clueless. + */ + break; + } + + case COMB_PLUS: + cur_node = get_prev_element_node (node_iface, cur_node); + if (!cur_node) + goto done; + break; + + case COMB_TILDE: /* General sibling selector. */ + { + CRXMLNodePtr n = NULL; + enum CRStatus status = CR_OK; + gboolean matches = FALSE; + + /* + * Walk through previous sibing nodes looking for a + * node that matches the preceding selector. + */ + for (n = get_prev_element_node (node_iface, cur_node); + n; + n = get_prev_element_node (node_iface, n)) { + status = sel_matches_node_real + (a_this, cur_sel->prev, + n, &matches, FALSE, TRUE); + + if (status != CR_OK) + goto done; + + if (matches == TRUE) { + cur_node = n ; + break; + } + } + + if (!n) { + /* + * Didn't find any previous sibling that matches + * the previous simple selector. + */ + goto done; + } + /* + * See note above in COMB_WS section. + */ + break; + } + + case COMB_GT: + cur_node = get_next_parent_element_node (node_iface, cur_node); + if (!cur_node) + goto done; + break; + + default: + goto done; + } + continue; + } + + /* + *if we reached this point, it means the selector matches + *the xml node. + */ + *a_result = TRUE; + + done: + return CR_OK; +} + + +/** + *Returns array of the ruleset statements that matches the + *given xml node. + *The engine keeps in memory the last statement he + *visited during the match. So, the next call + *to this function will eventually return a rulesets list starting + *from the last ruleset statement visited during the previous call. + *The enable users to get matching rulesets in an incremental way. + *Note that for each statement returned, + *the engine calculates the specificity of the selector + *that matched the xml node and stores it in the "specifity" field + *of the statement structure. + * + *@param a_sel_eng the current selection engine + *@param a_node the xml node for which the request + *is being made. + *@param a_sel_list the list of selectors to perform the search in. + *@param a_rulesets in/out parameter. A pointer to the + *returned array of rulesets statements that match the xml node + *given in parameter. The caller allocates the array before calling this + *function. + *@param a_len in/out parameter the length (in sizeof (#CRStatement*)) + *of the returned array. + *(the length of a_rulesets, more precisely). + *The caller must set it to the length of a_ruleset prior to calling this + *function. In return, the function sets it to the length + *(in sizeof (#CRStatement)) of the actually returned CRStatement array. + *@return CR_OUTPUT_TOO_SHORT_ERROR if found more rulesets than the size + *of the a_rulesets array. In this case, the first *a_len rulesets found + *are put in a_rulesets, and a further call will return the following + *ruleset(s) following the same principle. + *@return CR_OK if all the rulesets found have been returned. In this + *case, *a_len is set to the actual number of ruleset found. + *@return CR_BAD_PARAM_ERROR in case any of the given parameter are + *bad (e.g null pointer). + *@return CR_ERROR if any other error occurred. + */ +static enum CRStatus +cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this, + CRStyleSheet * a_stylesheet, + CRXMLNodePtr a_node, + CRStatement *** a_rulesets, + gulong * a_len, + gulong * a_capacity) +{ + CRStatement *cur_stmt = NULL; + CRSelector *sel_list = NULL, + *cur_sel = NULL; + gboolean matches = FALSE; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this + && a_stylesheet + && a_node && a_rulesets, CR_BAD_PARAM_ERROR); + + if (!a_stylesheet->statements) { + return CR_OK; + } + + /* + *if this stylesheet is "new one" + *let's remember it for subsequent calls. + */ + if (PRIVATE (a_this)->sheet != a_stylesheet) { + PRIVATE (a_this)->sheet = a_stylesheet; + PRIVATE (a_this)->cur_stmt = a_stylesheet->statements; + } + + /* + *walk through the list of statements and, + *get the selectors list inside the statements that + *contain some, and try to match our xml node in these + *selectors lists. + */ + for (cur_stmt = PRIVATE (a_this)->cur_stmt; + (PRIVATE (a_this)->cur_stmt = cur_stmt); + cur_stmt = cur_stmt->next) { + /* + *initialize the selector list in which we will + *really perform the search. + */ + sel_list = NULL; + + /* + *get the damn selector list in + *which we have to look + */ + switch (cur_stmt->type) { + case RULESET_STMT: + if (cur_stmt->kind.ruleset + && cur_stmt->kind.ruleset->sel_list) { + sel_list = cur_stmt->kind.ruleset->sel_list; + } + break; + + case AT_MEDIA_RULE_STMT: + if (cur_stmt->kind.media_rule + && cur_stmt->kind.media_rule->rulesets + && cur_stmt->kind.media_rule->rulesets-> + kind.ruleset + && cur_stmt->kind.media_rule->rulesets-> + kind.ruleset->sel_list) { + sel_list = + cur_stmt->kind.media_rule-> + rulesets->kind.ruleset->sel_list; + } + break; + + case AT_IMPORT_RULE_STMT: + if (cur_stmt->kind.import_rule) { + g_assert(!cur_stmt->kind.import_rule->sheet || + !cur_stmt->kind.import_rule->sheet->next); + cr_sel_eng_get_matched_rulesets_real ( + a_this, cur_stmt->kind.import_rule->sheet, + a_node, a_rulesets, + a_len, a_capacity); + } + break; + default: + break; + } + + if (!sel_list) + continue; + + /* + *now, we have a comma separated selector list to look in. + *let's walk it and try to match the xml_node + *on each item of the list. + */ + for (cur_sel = sel_list; cur_sel; cur_sel = cur_sel->next) { + if (!cur_sel->simple_sel) + continue; + + status = cr_sel_eng_matches_node + (a_this, cur_sel->simple_sel, + a_node, &matches); + + if (status == CR_OK && matches == TRUE) { + /* + *bingo!!! we found one ruleset that + *matches that fucking node. + *lets put it in the out array. + */ + + if (*a_len >= *a_capacity) { + *a_capacity = (*a_len) + 8; + *a_rulesets = (CRStatement **) g_try_realloc (*a_rulesets, + (*a_capacity) * sizeof (CRStatement *)); + if (!*a_rulesets) { + cr_utils_trace_info("Out of memory"); + return CR_ERROR; + } + } + + { + (*a_rulesets)[(*a_len)++] = cur_stmt; + + /* + *For the cascade computing algorithm + *(which is gonna take place later) + *we must compute the specificity + *(css2 spec chap 6.4.1) of the selector + *that matched the current xml node + *and store it in the css2 statement + *(statement == ruleset here). + */ + status = cr_simple_sel_compute_specificity (cur_sel->simple_sel); + + g_return_val_if_fail (status == CR_OK, + CR_ERROR); + cur_stmt->specificity = + cur_sel->simple_sel-> + specificity; + } + } + } + } + + /* + *if we reached this point, it means + *we reached the end of stylesheet. + *no need to store any info about the stylesheet + *anymore. + */ + g_return_val_if_fail (!PRIVATE (a_this)->cur_stmt, CR_ERROR); + PRIVATE (a_this)->sheet = NULL; + return CR_OK; +} + +static enum CRStatus +put_css_properties_in_props_list (CRPropList ** a_props, CRStatement * a_stmt) +{ + CRPropList *props = NULL, + *pair = NULL, + *tmp_props = NULL; + CRDeclaration *cur_decl = NULL; + + g_return_val_if_fail (a_props && a_stmt + && a_stmt->type == RULESET_STMT + && a_stmt->kind.ruleset, CR_BAD_PARAM_ERROR); + + props = *a_props; + + for (cur_decl = a_stmt->kind.ruleset->decl_list; + cur_decl; cur_decl = cur_decl->next) { + CRDeclaration *decl; + + decl = NULL; + pair = NULL; + + if (!cur_decl->property + || !cur_decl->property->stryng + || !cur_decl->property->stryng->str) + continue; + /* + *First, test if the property is not + *already present in our properties list + *If yes, apply the cascading rules to + *compute the precedence. If not, insert + *the property into the list + */ + cr_prop_list_lookup_prop (props, + cur_decl->property, + &pair); + + if (!pair) { + tmp_props = cr_prop_list_append2 + (props, cur_decl->property, cur_decl); + if (tmp_props) { + props = tmp_props; + tmp_props = NULL; + } + continue; + } + + /* + *A property with the same name already exists. + *We must apply here + *some cascading rules + *to compute the precedence. + */ + cr_prop_list_get_decl (pair, &decl); + g_return_val_if_fail (decl, CR_ERROR); + + /* + *first, look at the origin. + *6.4.1 says: + *"for normal declarations, + *author style sheets override user + *style sheets which override + *the default style sheet." + */ + if (decl->parent_statement + && decl->parent_statement->parent_sheet + && (decl->parent_statement->parent_sheet->origin + < a_stmt->parent_sheet->origin)) { + /* + *if the already selected declaration + *is marked as being !important the current + *declaration must not override it + *(unless the already selected declaration + *has an UA origin) + */ + if (decl->important == TRUE && cur_decl->important != TRUE + && decl->parent_statement->parent_sheet->origin + != ORIGIN_UA) { + continue; + } + tmp_props = cr_prop_list_unlink (props, pair); + if (props) { + cr_prop_list_destroy (pair); + } + props = tmp_props; + tmp_props = NULL; + props = cr_prop_list_append2 + (props, cur_decl->property, cur_decl); + + continue; + } else if (decl->parent_statement + && decl->parent_statement->parent_sheet + && (decl->parent_statement-> + parent_sheet->origin + > a_stmt->parent_sheet->origin)) { + cr_utils_trace_info + ("We should not reach this line\n"); + continue; + } + + /* + *A property with the same + *name and the same origin already exists. + *shit. This is lasting longer than expected ... + *Luckily, the spec says in 6.4.1: + *"more specific selectors will override + *more general ones" + *and + *"if two rules have the same weight, + *origin and specificity, + *the later specified wins" + */ + if (a_stmt->specificity + >= decl->parent_statement->specificity) { + if (decl->important == TRUE && cur_decl->important != TRUE) + continue; + props = cr_prop_list_unlink (props, pair); + if (pair) { + cr_prop_list_destroy (pair); + pair = NULL; + } + props = cr_prop_list_append2 (props, + cur_decl->property, + cur_decl); + } + } + /*TODO: this may leak. Check this out */ + *a_props = props; + + return CR_OK; +} + +static void +set_style_from_props (CRStyle * a_style, CRPropList * a_props) +{ + CRPropList *cur = NULL; + CRDeclaration *decl = NULL; + + for (cur = a_props; cur; cur = cr_prop_list_get_next (cur)) { + cr_prop_list_get_decl (cur, &decl); + cr_style_set_style_from_decl (a_style, decl); + decl = NULL; + } +} + +/**************************************** + *PUBLIC METHODS + ****************************************/ + +/** + * cr_sel_eng_new: + *Creates a new instance of #CRSelEng. + * + *@a_node_iface: Node interface + * + *Returns the newly built instance of #CRSelEng of + *NULL if an error occurs. + */ +CRSelEng * +cr_sel_eng_new (CRNodeIface const * a_node_iface) +{ + CRSelEng *result = NULL; + + result = (CRSelEng *) g_try_malloc (sizeof (CRSelEng)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSelEng)); + + PRIVATE (result) = (CRSelEngPriv *) g_try_malloc (sizeof (CRSelEngPriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRSelEngPriv)); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "root", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + root_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "empty", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + empty_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "lang", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + lang_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "only-child", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + only_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "only-of-type", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + only_of_type_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "first-child", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + first_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "first-of-type", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + first_of_type_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "last-child", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + last_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "last-of-type", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + last_of_type_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "nth-child", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + nth_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "nth-of-type", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + nth_of_type_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "nth-last-child", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + nth_last_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, (guchar *) "nth-last-of-type", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + nth_last_of_type_pseudo_class_handler); + + cr_sel_eng_set_node_iface (result, a_node_iface); + + return result; +} + +/** + * cr_sel_eng_register_pseudo_class_sel_handler: + *@a_this: the current instance of #CRSelEng + *@a_pseudo_class_sel_name: the name of the pseudo class selector. + *@a_pseudo_class_type: the type of the pseudo class selector. + *@a_handler: the actual handler or callback to be called during + *the selector evaluation process. + * + *Adds a new handler entry in the handlers entry table. + * + *Returns CR_OK, upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this, + guchar * a_name, + enum CRPseudoType a_type, + CRPseudoClassSelectorHandler + a_handler) +{ + struct CRPseudoClassSelHandlerEntry *handler_entry = NULL; + GList *list = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_handler && a_name, CR_BAD_PARAM_ERROR); + + handler_entry = (struct CRPseudoClassSelHandlerEntry *) g_try_malloc + (sizeof (struct CRPseudoClassSelHandlerEntry)); + if (!handler_entry) { + return CR_OUT_OF_MEMORY_ERROR; + } + memset (handler_entry, 0, + sizeof (struct CRPseudoClassSelHandlerEntry)); + handler_entry->name = (guchar *) g_strdup ((const gchar *) a_name); + handler_entry->type = a_type; + handler_entry->handler = a_handler; + list = g_list_append (PRIVATE (a_this)->pcs_handlers, handler_entry); + if (!list) { + return CR_OUT_OF_MEMORY_ERROR; + } + PRIVATE (a_this)->pcs_handlers = list; + return CR_OK; +} + +enum CRStatus +cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng * a_this, + guchar * a_name, + enum CRPseudoType a_type) +{ + GList *elem = NULL, + *deleted_elem = NULL; + gboolean found = FALSE; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!strcmp ((const char *) entry->name, (const char *) a_name) + && entry->type == a_type) { + found = TRUE; + break; + } + } + if (found == FALSE) + return CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR; + PRIVATE (a_this)->pcs_handlers = g_list_delete_link + (PRIVATE (a_this)->pcs_handlers, elem); + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (entry->name) { + g_free (entry->name); + entry->name = NULL; + } + g_free (elem); + g_list_free (deleted_elem); + + return CR_OK; +} + +/** + * cr_sel_eng_unregister_all_pseudo_class_sel_handlers: + *@a_this: the current instance of #CRSelEng . + * + *Unregisters all the pseudo class sel handlers + *and frees all the associated allocated datastructures. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng * a_this) +{ + GList *elem = NULL; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->pcs_handlers) + return CR_OK; + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!entry) + continue; + if (entry->name) { + g_free (entry->name); + entry->name = NULL; + } + g_free (entry); + elem->data = NULL; + } + g_list_free (PRIVATE (a_this)->pcs_handlers); + PRIVATE (a_this)->pcs_handlers = NULL; + return CR_OK; +} + +enum CRStatus +cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng * a_this, + guchar * a_name, + enum CRPseudoType a_type, + CRPseudoClassSelectorHandler * + a_handler) +{ + GList *elem = NULL; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + gboolean found = FALSE; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_name, CR_BAD_PARAM_ERROR); + + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!strcmp ((const char *) a_name, (const char *) entry->name) + && entry->type == a_type) { + found = TRUE; + break; + } + } + + if (found == FALSE) + return CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR; + *a_handler = entry->handler; + return CR_OK; +} + +/** + * cr_sel_eng_matches_node: + *@a_this: the selection engine. + *@a_sel: the simple selector against which the xml node + *is going to be matched. + *@a_node: the node against which the selector is going to be matched. + *@a_result: out parameter. The result of the match. Is set to + *TRUE if the selector matches the node, FALSE otherwise. This value + *is considered if and only if this functions returns CR_OK. + * + *Evaluates a chained list of simple selectors (known as a css2 selector). + *Says whether if this selector matches the xml node given in parameter or + *not. + * + *Returns the CR_OK if the selection ran correctly, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_matches_node (CRSelEng * a_this, CRSimpleSel * a_sel, + CRXMLNodePtr a_node, gboolean * a_result) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_this && a_node + && a_result, CR_BAD_PARAM_ERROR); + + if (!PRIVATE(a_this)->node_iface->isElementNode (a_node)) { + *a_result = FALSE; + return CR_OK; + } + + return sel_matches_node_real (a_this, a_sel, + a_node, a_result, + TRUE, TRUE); +} + +/** + * cr_sel_eng_get_matched_rulesets: + *@a_this: the current instance of the selection engine. + *@a_sheet: the stylesheet that holds the selectors. + *@a_node: the xml node to consider during the walk through + *the stylesheet. + *@a_rulesets: out parameter. A pointer to an array of + *rulesets statement pointers. *a_rulesets is allocated by + *this function and must be freed by the caller. However, the caller + *must not alter the rulesets statements pointer because they + *point to statements that are still in the css stylesheet. + *@a_len: the length of *a_ruleset. + * + *Returns an array of pointers to selectors that matches + *the xml node given in parameter. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_get_matched_rulesets (CRSelEng * a_this, + CRStyleSheet * a_sheet, + CRXMLNodePtr a_node, + CRStatement *** a_rulesets, gulong * a_len) +{ + CRStatement **stmts_tab = NULL; + enum CRStatus status = CR_OK; + gulong capacity = 0; + + g_return_val_if_fail (a_this + && a_sheet + && a_node + && a_rulesets && *a_rulesets == NULL + && a_len, CR_BAD_PARAM_ERROR); + + *a_len = 0; + + status = cr_sel_eng_get_matched_rulesets_real + (a_this, a_sheet, a_node, &stmts_tab, a_len, &capacity); + if (status == CR_ERROR) + goto error; + + *a_rulesets = stmts_tab; + + return CR_OK; + + error: + + if (stmts_tab) { + g_free (stmts_tab); + stmts_tab = NULL; + + } + + *a_len = 0; + return status; +} + +/** + * Like cr_sel_eng_get_matched_rulesets_real, but process an entire (linked) + * list of stylesheets, not only a single one. + */ +static +enum CRStatus +cr_sel_eng_process_stylesheet ( CRSelEng * a_eng, + CRXMLNodePtr a_node, + CRStyleSheet * a_stylesheet, + CRStatement *** stmts_tab, + gulong * tab_size, + gulong * tab_len, + gulong * index) +{ + enum CRStatus status = CR_OK; + CRStyleSheet *cur = NULL; + + for (cur = a_stylesheet; cur && status == CR_OK; cur = cur->next) { + status = cr_sel_eng_get_matched_rulesets_real + (a_eng, cur, a_node, stmts_tab, index, tab_size); + } + + return status; +} + +enum CRStatus +cr_sel_eng_get_matched_properties_from_cascade (CRSelEng * a_this, + CRCascade * a_cascade, + CRXMLNodePtr a_node, + CRPropList ** a_props) +{ + CRStatement **stmts_tab = NULL; + enum CRStatus status = CR_OK; + gulong tab_size = 0, + tab_len = 0, + i = 0, + index = 0; + enum CRStyleOrigin origin; + CRStyleSheet *sheet = NULL; + + g_return_val_if_fail (a_this + && a_cascade + && a_node && a_props, CR_BAD_PARAM_ERROR); + + for (origin = ORIGIN_UA; origin < NB_ORIGINS; origin = (enum CRStyleOrigin) (origin + 1)) { + sheet = cr_cascade_get_sheet (a_cascade, origin); + if (!sheet) + continue; + + status = cr_sel_eng_process_stylesheet (a_this, a_node, sheet, &stmts_tab, &tab_size, &tab_len, &index); + if (status != CR_OK) { + cr_utils_trace_info ("Error while running " + "selector engine"); + return status; + } + } + + /* + *TODO, walk down the stmts_tab and build the + *property_name/declaration hashtable. + *Make sure one can walk from the declaration to + *the stylesheet. + */ + for (i = 0; i < index; i++) { + CRStatement *stmt = stmts_tab[i]; + if (!stmt) + continue; + switch (stmt->type) { + case RULESET_STMT: + if (!stmt->parent_sheet) + continue; + status = put_css_properties_in_props_list + (a_props, stmt); + break; + default: + break; + } + + } + status = CR_OK ; + if (stmts_tab) { + g_free (stmts_tab); + stmts_tab = NULL; + } + + return status; +} + +enum CRStatus +cr_sel_eng_get_matched_style (CRSelEng * a_this, + CRCascade * a_cascade, + CRXMLNodePtr a_node, + CRStyle * a_parent_style, + CRStyle ** a_style, + gboolean a_set_props_to_initial_values) +{ + enum CRStatus status = CR_OK; + + CRPropList *props = NULL; + + g_return_val_if_fail (a_this && a_cascade + && a_node && a_style, CR_BAD_PARAM_ERROR); + + status = cr_sel_eng_get_matched_properties_from_cascade + (a_this, a_cascade, a_node, &props); + + g_return_val_if_fail (status == CR_OK, status); + if (props) { + if (!*a_style) { + *a_style = cr_style_new (a_set_props_to_initial_values) ; + g_return_val_if_fail (*a_style, CR_ERROR); + } else { + if (a_set_props_to_initial_values == TRUE) { + cr_style_set_props_to_initial_values (*a_style) ; + } else { + cr_style_set_props_to_default_values (*a_style); + } + } + (*a_style)->parent_style = a_parent_style; + + set_style_from_props (*a_style, props); + if (props) { + cr_prop_list_destroy (props); + props = NULL; + } + } + return CR_OK; +} + +/** + * cr_sel_eng_destroy: + *@a_this: the current instance of the selection engine. + * + *The destructor of #CRSelEng + */ +void +cr_sel_eng_destroy (CRSelEng * a_this) +{ + g_return_if_fail (a_this); + + if (!PRIVATE (a_this)) + goto end ; + if (PRIVATE (a_this)->pcs_handlers) { + cr_sel_eng_unregister_all_pseudo_class_sel_handlers + (a_this) ; + PRIVATE (a_this)->pcs_handlers = NULL ; + } + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + end: + if (a_this) { + g_free (a_this); + } +} diff --git a/src/3rdparty/libcroco/src/cr-sel-eng.h b/src/3rdparty/libcroco/src/cr-sel-eng.h new file mode 100644 index 0000000..c666f48 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-sel-eng.h @@ -0,0 +1,118 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_SEL_ENG_H__ +#define __CR_SEL_ENG_H__ + +#include "cr-utils.h" +#include "cr-stylesheet.h" +#include "cr-cascade.h" +#include "cr-style.h" +#include "cr-prop-list.h" +#include "cr-node-iface.h" + +/** + *@file: + *The declaration of the #CRSelEng class. + *The #CRSelEng is actually the "Selection Engine" + *class. + */ + +G_BEGIN_DECLS + +typedef struct _CRSelEng CRSelEng ; +typedef struct _CRSelEngPriv CRSelEngPriv ; +typedef struct _CRArguments CRArguments ; + +//stores arguments of function of type an+b +struct _CRArguments +{ + int a; + int b; +} ; + +/** + *The Selection engine class. + *The main service provided by this class, is + *the ability to interpret a libcroco implementation + *of css2 selectors, and given an xml node, say if + *the selector matches the node or not. + */ +struct _CRSelEng +{ + CRSelEngPriv *priv ; +} ; + +void cr_sel_eng_set_node_iface(CRSelEng *a_this, CRNodeIface const *); + +typedef gboolean (*CRPseudoClassSelectorHandler) (CRSelEng* a_this, + CRAdditionalSel *a_add_sel, + CRXMLNodePtr a_node) ; +CRSelEng * cr_sel_eng_new (CRNodeIface const *); + +enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng *a_this, + guchar *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type, + CRPseudoClassSelectorHandler a_handler) ; + +enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng *a_this, + guchar *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type) ; + +enum CRStatus cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng *a_this) ; + +enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng *a_this, + guchar *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type, + CRPseudoClassSelectorHandler *a_handler) ; + +enum CRStatus cr_sel_eng_matches_node (CRSelEng *a_this, + CRSimpleSel *a_sel, + CRXMLNodePtr a_node, + gboolean *a_result) ; + +enum CRStatus cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, + CRStyleSheet *a_sheet, + CRXMLNodePtr a_node, + CRStatement ***a_rulesets, + gulong *a_len) ; + +enum CRStatus +cr_sel_eng_get_matched_properties_from_cascade (CRSelEng *a_this, + CRCascade *a_cascade, + CRXMLNodePtr a_node, + CRPropList **a_props) ; + +enum CRStatus cr_sel_eng_get_matched_style (CRSelEng *a_this, + CRCascade *a_cascade, + CRXMLNodePtr a_node, + CRStyle *a_parent_style, + CRStyle **a_style, + gboolean a_set_props_to_initial_values) ; + +void cr_sel_eng_destroy (CRSelEng *a_this) ; + +G_END_DECLS + + +#endif/*__CR_SEL_ENG_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-selector.c b/src/3rdparty/libcroco/src/cr-selector.c new file mode 100644 index 0000000..496b02c --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-selector.c @@ -0,0 +1,333 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-selector.h" +#include "cr-parser.h" + +/** + * cr_selector_new: + * + *@a_simple_sel: the initial simple selector list + *of the current instance of #CRSelector. + * + *Creates a new instance of #CRSelector. + * + *Returns the newly built instance of #CRSelector, or + *NULL in case of failure. + */ +CRSelector * +cr_selector_new (CRSimpleSel * a_simple_sel) +{ + CRSelector *result = NULL; + + result = (CRSelector *) g_try_malloc (sizeof (CRSelector)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSelector)); + result->simple_sel = a_simple_sel; + return result; +} + +/** + * cr_selector_parse_from_buf: + * + *@a_char_buf: the buffer to parse. + *@a_enc: the encoding of the input buffer a_char_buf. + * + *Parses a buf for selectors. + * + *Fix Me: parsing will fail for some cases if buf does not end with '{'. + * + *Returns the newly built instance of #CRSelector, or + *NULL in case of failure. + */ +CRSelector * +cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc) +{ + CRParser *parser = NULL; + CRSelector *selector = NULL; + enum CRStatus status; + + g_return_val_if_fail (a_char_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen ((const char *) a_char_buf), + a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + + status = cr_parser_parse_selector (parser, &selector); + + if (status != CR_OK) { + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + } + + cr_parser_destroy(parser); + + return selector; +} + +/** + * cr_selector_append: + * + *@a_this: the current instance of #CRSelector. + *@a_new: the instance of #CRSelector to be appended. + * + *Appends a new instance of #CRSelector to the current selector list. + * + *Returns the new list. + */ +CRSelector * +cr_selector_append (CRSelector * a_this, CRSelector * a_new) +{ + CRSelector *cur = NULL; + + if (!a_this) { + return a_new; + } + + /*walk forward the list headed by a_this to get the list tail */ + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + * cr_selector_prepend: + * + *@a_this: the current instance of #CRSelector list. + *@a_new: the instance of #CRSelector. + * + *Prepends an element to the #CRSelector list. + * + *Returns the new list. + */ +CRSelector * +cr_selector_prepend (CRSelector * a_this, CRSelector * a_new) +{ + CRSelector *cur = NULL; + + a_new->next = a_this; + a_this->prev = a_new; + + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + * cr_selector_append_simple_sel: + * + *@a_this: the current instance of #CRSelector. + *@a_simple_sel: the simple selector to append. + * + *append a simple selector to the current #CRSelector list. + * + *Returns the new list or NULL in case of failure. + */ +CRSelector * +cr_selector_append_simple_sel (CRSelector * a_this, + CRSimpleSel * a_simple_sel) +{ + CRSelector *selector = NULL; + + selector = cr_selector_new (a_simple_sel); + g_return_val_if_fail (selector, NULL); + + return cr_selector_append (a_this, selector); +} + +guchar * +cr_selector_to_string (CRSelector const * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + str_buf = (GString *) g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if (a_this) { + CRSelector const *cur = NULL; + + for (cur = a_this; cur; cur = cur->next) { + if (cur->simple_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_simple_sel_to_string + (cur->simple_sel); + + if (tmp_str) { + if (cur->prev) + g_string_append (str_buf, + ", "); + + g_string_append (str_buf, (const gchar *) tmp_str); + + g_free (tmp_str); + tmp_str = NULL; + } + } + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + * cr_selector_dump: + * + *@a_this: the current instance of #CRSelector. + *@a_fp: the destination file. + * + *Serializes the current instance of #CRSelector to a file. + */ +void +cr_selector_dump (CRSelector const * a_this, FILE * a_fp) +{ + guchar *tmp_buf = NULL; + + if (a_this) { + tmp_buf = cr_selector_to_string (a_this); + if (tmp_buf) { + fprintf (a_fp, "%s", tmp_buf); + g_free (tmp_buf); + tmp_buf = NULL; + } + } +} + +/** + * cr_selector_ref: + * + *@a_this: the current instance of #CRSelector. + * + *Increments the ref count of the current instance + *of #CRSelector. + */ +void +cr_selector_ref (CRSelector * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + * cr_selector_unref: + * + *@a_this: the current instance of #CRSelector. + * + *Decrements the ref count of the current instance of + *#CRSelector. + *If the ref count reaches zero, the current instance of + *#CRSelector is destroyed. + * + *Returns TRUE if this function destroyed the current instance + *of #CRSelector, FALSE otherwise. + */ +gboolean +cr_selector_unref (CRSelector * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_selector_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + * cr_selector_destroy: + * + *@a_this: the current instance of #CRSelector. + * + *Destroys the selector list. + */ +void +cr_selector_destroy (CRSelector * a_this) +{ + CRSelector *cur = NULL; + + g_return_if_fail (a_this); + + /* + *go and get the list tail. In the same time, free + *all the simple selectors contained in the list. + */ + for (cur = a_this; cur && cur->next; cur = cur->next) { + if (cur->simple_sel) { + cr_simple_sel_destroy (cur->simple_sel); + cur->simple_sel = NULL; + } + } + + if (cur) { + if (cur->simple_sel) { + cr_simple_sel_destroy (cur->simple_sel); + cur->simple_sel = NULL; + } + } + + /*in case the list has only one element */ + if (cur && !cur->prev) { + g_free (cur); + return; + } + + /*walk backward the list and free each "next element" */ + for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + } + + if (!cur) + return; + + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + + g_free (cur); +} diff --git a/src/3rdparty/libcroco/src/cr-selector.h b/src/3rdparty/libcroco/src/cr-selector.h new file mode 100644 index 0000000..a7e0295 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-selector.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_SELECTOR_H__ +#define __CR_SELECTOR_H__ + +#include <stdio.h> +#include "cr-utils.h" +#include "cr-simple-sel.h" +#include "cr-parsing-location.h" + +/** + *@file + *The declaration file of the #CRSelector file. + */ + +G_BEGIN_DECLS + +typedef struct _CRSelector CRSelector ; + +/** + *Abstracts a CSS2 selector as defined in the right part + *of the 'ruleset' production in the appendix D.1 of the + *css2 spec. + *It is actually the abstraction of a comma separated list + *of simple selectors list. + *In a css2 file, a selector is a list of simple selectors + *separated by a comma. + *e.g: sel0, sel1, sel2 ... + *Each seln is a simple selector + */ +struct _CRSelector +{ + /** + *A Selection expression. + *It is a list of basic selectors. + *Each basic selector can be either an element + *selector, an id selector, a class selector, an + *attribute selector, an universal selector etc ... + */ + CRSimpleSel *simple_sel ; + + /**The next selector list element*/ + CRSelector *next ; + CRSelector *prev ; + CRParsingLocation location ; + glong ref_count ; +}; + +CRSelector* cr_selector_new (CRSimpleSel *a_sel_expr) ; + +CRSelector * cr_selector_parse_from_buf (const guchar * a_char_buf, + enum CREncoding a_enc) ; + +CRSelector* cr_selector_append (CRSelector *a_this, CRSelector *a_new) ; + +CRSelector* cr_selector_append_simple_sel (CRSelector *a_this, + CRSimpleSel *a_simple_sel) ; + +CRSelector* cr_selector_prepend (CRSelector *a_this, CRSelector *a_new) ; + +guchar * cr_selector_to_string (CRSelector const *a_this) ; + +void cr_selector_dump (CRSelector const *a_this, FILE *a_fp) ; + +void cr_selector_ref (CRSelector *a_this) ; + +gboolean cr_selector_unref (CRSelector *a_this) ; + +void cr_selector_destroy (CRSelector *a_this) ; + +G_END_DECLS + +#endif /*__CR_SELECTOR_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-simple-sel.c b/src/3rdparty/libcroco/src/cr-simple-sel.c new file mode 100644 index 0000000..095c159 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-simple-sel.c @@ -0,0 +1,322 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include <glib.h> +#include "cr-simple-sel.h" + +/** + * cr_simple_sel_new: + * + *The constructor of #CRSimpleSel. + * + *Returns the new instance of #CRSimpleSel. + */ +CRSimpleSel * +cr_simple_sel_new (void) +{ + CRSimpleSel *result = NULL; + + result = (CRSimpleSel *) g_try_malloc (sizeof (CRSimpleSel)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSimpleSel)); + + return result; +} + +/** + * cr_simple_sel_append_simple_sel: + * + *Appends a simpe selector to the current list of simple selector. + * + *@a_this: the this pointer of the current instance of #CRSimpleSel. + *@a_sel: the simple selector to append. + * + *Returns: the new list upon successful completion, an error code otherwise. + */ +CRSimpleSel * +cr_simple_sel_append_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel) +{ + CRSimpleSel *cur = NULL; + + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) + return a_sel; + + for (cur = a_this; cur->next; cur = cur->next) ; + + cur->next = a_sel; + a_sel->prev = cur; + + return a_this; +} + +/** + * cr_simple_sel_prepend_simple_sel: + * + *@a_this: the this pointer of the current instance of #CRSimpleSel. + *@a_sel: the simple selector to prepend. + * + *Prepends a simple selector to the current list of simple selectors. + * + *Returns the new list upon successful completion, an error code otherwise. + */ +CRSimpleSel * +cr_simple_sel_prepend_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel) +{ + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) + return a_sel; + + a_sel->next = a_this; + a_this->prev = a_sel; + + return a_sel; +} + +guchar * +cr_simple_sel_to_string (CRSimpleSel const * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL; + + CRSimpleSel const *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + for (cur = a_this; cur; cur = cur->next) { + if (cur->name) { + gchar const *str = cur->name->stryng->str; + + if (str) { + switch (cur->combinator) { + case COMB_WS: + g_string_append (str_buf, " "); + break; + + case COMB_PLUS: + g_string_append (str_buf, "+"); + break; + + case COMB_TILDE: + g_string_append (str_buf, "~"); + break; + + case COMB_GT: + g_string_append (str_buf, ">"); + break; + + default: + break; + } + + g_string_append (str_buf, (const gchar *) str); + } + } + + if (cur->add_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_additional_sel_to_string (cur->add_sel); + if (tmp_str) { + g_string_append (str_buf, (const gchar *) tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + + +guchar * +cr_simple_sel_one_to_string (CRSimpleSel const * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + if (a_this->name) { + gchar const *str = a_this->name->stryng->str; + + if (str) { + g_string_append_printf (str_buf, "%s", str); + } + } + + if (a_this->add_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_additional_sel_to_string (a_this->add_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + * cr_simple_sel_dump: + *@a_this: the current instance of #CRSimpleSel. + *@a_fp: the destination file pointer. + * + *Dumps the selector to a file. + *TODO: add the support of unicode in the dump. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_simple_sel_dump (CRSimpleSel const * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_val_if_fail (a_fp, CR_BAD_PARAM_ERROR); + + if (a_this) { + tmp_str = cr_simple_sel_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + + return CR_OK; +} + +/** + * cr_simple_sel_compute_specificity: + * + *@a_this: the current instance of #CRSimpleSel + * + *Computes the selector (combinator separated list of simple selectors) + *as defined in the css2 spec in chapter 6.4.3 + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_simple_sel_compute_specificity (CRSimpleSel * a_this) +{ + CRAdditionalSel const *cur_add_sel = NULL; + CRSimpleSel const *cur_sel = NULL; + gulong a = 0, + b = 0, + c = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (cur_sel = a_this; cur_sel; cur_sel = cur_sel->next) { + if (cur_sel->type_mask & TYPE_SELECTOR) { + c++; /*hmmh, is this a new language ? */ + } else if (!cur_sel->name + || !cur_sel->name->stryng + || !cur_sel->name->stryng->str) { + if (cur_sel->add_sel->type == + PSEUDO_CLASS_ADD_SELECTOR) { + /* + *this is a pseudo element, and + *the spec says, "ignore pseudo elements". + */ + continue; + } + } + + for (cur_add_sel = cur_sel->add_sel; + cur_add_sel; cur_add_sel = cur_add_sel->next) { + switch (cur_add_sel->type) { + case ID_ADD_SELECTOR: + a++; + break; + + case NO_ADD_SELECTOR: + continue; + + default: + b++; + break; + } + } + } + + /*we suppose a, b and c have 1 to 3 digits */ + a_this->specificity = a * 1000000 + b * 1000 + c; + + return CR_OK; +} + +/** + * cr_simple_sel_destroy: + * + *@a_this: the this pointer of the current instance of #CRSimpleSel. + * + *The destructor of the current instance of + *#CRSimpleSel. Recursively calls the destructor of #CRSimpleSel->next + */ +void +cr_simple_sel_destroy (CRSimpleSel * const a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->add_sel) { + cr_additional_sel_destroy (a_this->add_sel); + a_this->add_sel = NULL; + } + + if (a_this->next) { + cr_simple_sel_destroy (a_this->next); + a_this->next = NULL; + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-simple-sel.h b/src/3rdparty/libcroco/src/cr-simple-sel.h new file mode 100644 index 0000000..e53f587 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-simple-sel.h @@ -0,0 +1,131 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + + +#ifndef __CR_SEL_H__ +#define __CR_SEL_H__ + +#include <stdio.h> +#include <glib.h> +#include "cr-additional-sel.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *the declaration of the #CRSimpleSel class. + * + */ +enum Combinator +{ + NO_COMBINATOR, + COMB_WS, /*whitespace: descendent*/ + COMB_PLUS, /*'+': immediately preceded by*/ + COMB_TILDE, /*'~': preceded by, CSS 3*/ + COMB_GT /*greater than ('>'): child*/ +} ; + +enum SimpleSelectorType +{ + NO_SELECTOR_TYPE = 0, + UNIVERSAL_SELECTOR = 1, + TYPE_SELECTOR = 1 << 1 +} ; + +typedef struct _CRSimpleSel CRSimpleSel ; + +/** + *The abstraction of a css2 simple selection list + *as defined by the right part of the "selector" production in the + *appendix D.1 of the css2 spec. + *It is basically a list of simple selector, each + *simple selector being separated by a combinator. + * + *In the libcroco's implementation, each simple selector + *is made of at most two parts: + * + *1/An element name or 'type selector' (which can hold a '*' and + *then been called 'universal selector') + * + *2/An additional selector that "specializes" the preceding type or + *universal selector. The additional selector can be either + *an id selector, or a class selector, or an attribute selector. + */ +struct _CRSimpleSel +{ + enum SimpleSelectorType type_mask ; + gboolean is_case_sentive ; + CRString * name ; + /** + *The combinator that separates + *this simple selector from the previous + *one. + */ + enum Combinator combinator ; + + /** + *The additional selector list of the + *current simple selector. + *An additional selector may + *be a class selector, an id selector, + *or an attribute selector. + *Note that this field is a linked list. + */ + CRAdditionalSel *add_sel ; + + /* + *the specificity as specified by + *chapter 6.4.3 of the spec. + */ + gulong specificity ; + + CRSimpleSel *next ; + CRSimpleSel *prev ; + CRParsingLocation location ; +} ; + +CRSimpleSel * cr_simple_sel_new (void) ; + +CRSimpleSel * cr_simple_sel_append_simple_sel (CRSimpleSel *a_this, + CRSimpleSel *a_sel) ; + +CRSimpleSel * cr_simple_sel_prepend_simple_sel (CRSimpleSel *a_this, + CRSimpleSel *a_sel) ; + +guchar * cr_simple_sel_to_string (CRSimpleSel const *a_this) ; + +guchar * cr_simple_sel_one_to_string (CRSimpleSel const * a_this) ; + +enum CRStatus cr_simple_sel_dump (CRSimpleSel const *a_this, FILE *a_fp) ; + +enum CRStatus cr_simple_sel_dump_attr_sel_list (CRSimpleSel const *a_this) ; + +enum CRStatus cr_simple_sel_compute_specificity (CRSimpleSel *a_this) ; + +void cr_simple_sel_destroy (CRSimpleSel *a_this) ; + +G_END_DECLS + + +#endif /*__CR_SIMPLE_SEL_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-statement.c b/src/3rdparty/libcroco/src/cr-statement.c new file mode 100644 index 0000000..d624e9f --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-statement.c @@ -0,0 +1,2810 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS files for copyrights information. + */ + +#include <string.h> +#include "cr-statement.h" +#include "cr-parser.h" + +/** + *@file + *Definition of the #CRStatement class. + */ + +#define DECLARATION_INDENT_NB 2 + +static void cr_statement_clear (CRStatement * a_this); + +static void +parse_font_face_start_font_face_cb (CRDocHandler * a_this, + CRParsingLocation *a_location) +{ + CRStatement *stmt = NULL; + enum CRStatus status = CR_OK; + + (void) a_location; + + stmt = cr_statement_new_at_font_face_rule (NULL, NULL); + g_return_if_fail (stmt); + + status = cr_doc_handler_set_ctxt (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_font_face_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + cr_doc_handler_set_ctxt (a_this, NULL); + return; + } +} + +static void +parse_font_face_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_value, gboolean a_important) +{ + enum CRStatus status = CR_OK; + CRString *name = NULL; + CRDeclaration *decl = NULL; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + (void) a_important; + + g_return_if_fail (a_this && a_name); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == AT_FONT_FACE_RULE_STMT); + + name = cr_string_dup (a_name) ; + g_return_if_fail (name); + decl = cr_declaration_new (stmt, name, a_value); + if (!decl) { + cr_utils_trace_info ("cr_declaration_new () failed."); + goto error; + } + name = NULL; + + stmt->kind.font_face_rule->decl_list = + cr_declaration_append (stmt->kind.font_face_rule->decl_list, + decl); + if (!stmt->kind.font_face_rule->decl_list) + goto error; + decl = NULL; + + error: + if (decl) { + cr_declaration_unref (decl); + decl = NULL; + } + if (name) { + cr_string_destroy (name); + name = NULL; + } +} + +static void +parse_font_face_end_font_face_cb (CRDocHandler * a_this) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + resultptr = &result; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) resultptr); + g_return_if_fail (status == CR_OK && result); + g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT); + + status = cr_doc_handler_set_result (a_this, result); + g_return_if_fail (status == CR_OK); +} + +static void +parse_page_start_page_cb (CRDocHandler * a_this, + CRString * a_name, + CRString * a_pseudo_page, + CRParsingLocation *a_location) +{ + CRStatement *stmt = NULL; + enum CRStatus status = CR_OK; + CRString *page_name = NULL, *pseudo_name = NULL ; + + (void) a_location; + + if (a_name) + page_name = cr_string_dup (a_name) ; + if (a_pseudo_page) + pseudo_name = cr_string_dup (a_pseudo_page) ; + + stmt = cr_statement_new_at_page_rule (NULL, NULL, + page_name, + pseudo_name); + page_name = NULL ; + pseudo_name = NULL ; + g_return_if_fail (stmt); + status = cr_doc_handler_set_ctxt (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_page_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_ctxt (a_this, NULL); + } +} + +static void +parse_page_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, gboolean a_important) +{ + CRString *name = NULL; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + CRDeclaration *decl = NULL; + enum CRStatus status = CR_OK; + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt->type == AT_PAGE_RULE_STMT); + + name = cr_string_dup (a_name); + g_return_if_fail (name); + + decl = cr_declaration_new (stmt, name, a_expression); + if (!decl) + cr_string_destroy(name); + g_return_if_fail (decl); + decl->important = a_important; + stmt->kind.page_rule->decl_list = + cr_declaration_append (stmt->kind.page_rule->decl_list, decl); + g_return_if_fail (stmt->kind.page_rule->decl_list); +} + +static void +parse_page_end_page_cb (CRDocHandler * a_this, + CRString * a_name, + CRString * a_pseudo_page) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + (void) a_name; + (void) a_pseudo_page; + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == AT_PAGE_RULE_STMT); + + status = cr_doc_handler_set_result (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_start_media_cb (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + GList *media_list = NULL; + + (void) a_location; + + g_return_if_fail (a_this && a_this->priv); + + if (a_media_list) { + /*duplicate media list */ + media_list = cr_utils_dup_glist_of_cr_string + (a_media_list); + } + + g_return_if_fail (media_list); + + /*make sure cr_statement_new_at_media_rule works in this case. */ + at_media = cr_statement_new_at_media_rule (NULL, NULL, media_list); + + status = cr_doc_handler_set_ctxt (a_this, at_media); + g_return_if_fail (status == CR_OK); + status = cr_doc_handler_set_result (a_this, at_media); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_unrecoverable_error_cb (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_ctxt (a_this, NULL); + cr_doc_handler_set_result (a_this, NULL); + } +} + +static void +parse_at_media_start_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + CRStatement **at_media_ptr = NULL; + CRStatement *ruleset = NULL; + + g_return_if_fail (a_this && a_this->priv && a_sellist); + + at_media_ptr = &at_media; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) at_media_ptr); + g_return_if_fail (status == CR_OK && at_media); + g_return_if_fail (at_media->type == AT_MEDIA_RULE_STMT); + ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, at_media); + g_return_if_fail (ruleset); + status = cr_doc_handler_set_ctxt (a_this, ruleset); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_property_cb (CRDocHandler * a_this, + CRString * a_name, CRTerm * a_value, + gboolean a_important) +{ + enum CRStatus status = CR_OK; + + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + CRDeclaration *decl = NULL; + CRString *name = NULL; + + g_return_if_fail (a_this && a_name); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, + (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == RULESET_STMT); + + name = cr_string_dup (a_name) ; + g_return_if_fail (name); + + decl = cr_declaration_new (stmt, name, a_value); + if (!decl) + cr_string_destroy(name); + g_return_if_fail (decl); + decl->important = a_important; + status = cr_statement_ruleset_append_decl (stmt, decl); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_end_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + enum CRStatus status = CR_OK; + + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + g_return_if_fail (a_this && a_sellist); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt + && stmt->type == RULESET_STMT); + g_return_if_fail (stmt->kind.ruleset->parent_media_rule); + + status = cr_doc_handler_set_ctxt + (a_this, stmt->kind.ruleset->parent_media_rule); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_end_media_cb (CRDocHandler * a_this, + GList * a_media_list) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + CRStatement **at_media_ptr = NULL; + + (void) a_media_list; + + g_return_if_fail (a_this && a_this->priv); + + at_media_ptr = &at_media; + status = cr_doc_handler_get_ctxt (a_this, + (gpointer *) at_media_ptr); + g_return_if_fail (status == CR_OK && at_media); + status = cr_doc_handler_set_result (a_this, at_media); +} + +static void +parse_ruleset_start_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + CRStatement *ruleset = NULL; + + g_return_if_fail (a_this && a_this->priv && a_sellist); + + ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, NULL); + g_return_if_fail (ruleset); + + cr_doc_handler_set_result (a_this, ruleset); +} + +static void +parse_ruleset_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + stmtptr = &stmt; + status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_result (a_this, NULL); + } +} + +static void +parse_ruleset_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_value, gboolean a_important) +{ + enum CRStatus status = CR_OK; + CRStatement *ruleset = NULL; + CRStatement **rulesetptr = NULL; + CRDeclaration *decl = NULL; + CRString *stringue = NULL; + + g_return_if_fail (a_this && a_this->priv && a_name); + + rulesetptr = &ruleset; + status = cr_doc_handler_get_result (a_this, (gpointer *) rulesetptr); + g_return_if_fail (status == CR_OK + && ruleset + && ruleset->type == RULESET_STMT); + + stringue = cr_string_dup (a_name); + g_return_if_fail (stringue); + + decl = cr_declaration_new (ruleset, stringue, a_value); + if (!decl) + cr_string_destroy (stringue); + g_return_if_fail (decl); + decl->important = a_important; + status = cr_statement_ruleset_append_decl (ruleset, decl); + g_return_if_fail (status == CR_OK); +} + +static void +parse_ruleset_end_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this && a_sellist); + + resultptr = &result; + status = cr_doc_handler_get_result (a_this, (gpointer *) resultptr); + + g_return_if_fail (status == CR_OK + && result + && result->type == RULESET_STMT); +} + +static void +cr_statement_clear (CRStatement * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case AT_RULE_STMT: + break; + case RULESET_STMT: + if (!a_this->kind.ruleset) + return; + if (a_this->kind.ruleset->sel_list) { + cr_selector_unref (a_this->kind.ruleset->sel_list); + a_this->kind.ruleset->sel_list = NULL; + } + if (a_this->kind.ruleset->decl_list) { + cr_declaration_destroy + (a_this->kind.ruleset->decl_list); + a_this->kind.ruleset->decl_list = NULL; + } + g_free (a_this->kind.ruleset); + a_this->kind.ruleset = NULL; + break; + + case AT_IMPORT_RULE_STMT: + if (!a_this->kind.import_rule) + return; + if (a_this->kind.import_rule->url) { + cr_string_destroy + (a_this->kind.import_rule->url) ; + a_this->kind.import_rule->url = NULL; + } + if (a_this->kind.import_rule->media_list) { + g_list_free_full (a_this->kind.import_rule->media_list, + (GDestroyNotify) cr_string_destroy); + } + if (a_this->kind.import_rule->sheet) { + cr_stylesheet_unref (a_this->kind.import_rule->sheet); + } + g_free (a_this->kind.import_rule); + a_this->kind.import_rule = NULL; + break; + + case AT_MEDIA_RULE_STMT: + if (!a_this->kind.media_rule) + return; + if (a_this->kind.media_rule->rulesets) { + cr_statement_destroy + (a_this->kind.media_rule->rulesets); + a_this->kind.media_rule->rulesets = NULL; + } + if (a_this->kind.media_rule->media_list) { + GList *cur = NULL; + + for (cur = a_this->kind.media_rule->media_list; + cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy ((CRString *) cur->data); + cur->data = NULL; + } + + } + g_list_free (a_this->kind.media_rule->media_list); + a_this->kind.media_rule->media_list = NULL; + } + g_free (a_this->kind.media_rule); + a_this->kind.media_rule = NULL; + break; + + case AT_PAGE_RULE_STMT: + if (!a_this->kind.page_rule) + return; + + if (a_this->kind.page_rule->decl_list) { + cr_declaration_destroy + (a_this->kind.page_rule->decl_list); + a_this->kind.page_rule->decl_list = NULL; + } + if (a_this->kind.page_rule->name) { + cr_string_destroy + (a_this->kind.page_rule->name); + a_this->kind.page_rule->name = NULL; + } + if (a_this->kind.page_rule->pseudo) { + cr_string_destroy + (a_this->kind.page_rule->pseudo); + a_this->kind.page_rule->pseudo = NULL; + } + g_free (a_this->kind.page_rule); + a_this->kind.page_rule = NULL; + break; + + case AT_CHARSET_RULE_STMT: + if (!a_this->kind.charset_rule) + return; + + if (a_this->kind.charset_rule->charset) { + cr_string_destroy + (a_this->kind.charset_rule->charset); + a_this->kind.charset_rule->charset = NULL; + } + g_free (a_this->kind.charset_rule); + a_this->kind.charset_rule = NULL; + break; + + case AT_FONT_FACE_RULE_STMT: + if (!a_this->kind.font_face_rule) + return; + + if (a_this->kind.font_face_rule->decl_list) { + cr_declaration_unref + (a_this->kind.font_face_rule->decl_list); + a_this->kind.font_face_rule->decl_list = NULL; + } + g_free (a_this->kind.font_face_rule); + a_this->kind.font_face_rule = NULL; + break; + + default: + break; + } +} + +/** + * cr_statement_ruleset_to_string: + * + *@a_this: the current instance of #CRStatement + *@a_indent: the number of whitespace to use for indentation + * + *Serializes the ruleset statement into a string + * + *Returns the newly allocated serialised string. Must be freed + *by the caller, using g_free(). + */ +static gchar * +cr_statement_ruleset_to_string (CRStatement const * a_this, glong a_indent) +{ + GString *stringue = NULL; + gchar *tmp_str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, NULL); + + stringue = (GString *) g_string_new (NULL); + if (!stringue) { + return result; + } + + if (a_this->kind.ruleset->sel_list) { + if (a_indent) + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + + tmp_str = + (gchar *) cr_selector_to_string (a_this->kind.ruleset-> + sel_list); + if (tmp_str) { + g_string_append (stringue, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + g_string_append (stringue, " {\n"); + if (a_this->kind.ruleset->decl_list) { + tmp_str = (gchar *) cr_declaration_list_to_string2 + (a_this->kind.ruleset->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE); + if (tmp_str) { + g_string_append (stringue, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append (stringue, "\n"); + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + } + g_string_append (stringue, "}"); + result = stringue->str; + + g_string_free (stringue, FALSE); + stringue = NULL; + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + return result; +} + + +/** + * cr_statement_font_face_rule_to_string: + * + *@a_this: the current instance of #CRStatement to consider + *It must be a font face rule statement. + *@a_indent: the number of white spaces of indentation. + * + *Serializes a font face rule statement into a string. + * + *Returns the serialized string. Must be deallocated by the caller + *using g_free(). + */ +static gchar * +cr_statement_font_face_rule_to_string (CRStatement const * a_this, + glong a_indent) +{ + gchar *result = NULL, *tmp_str = NULL ; + GString *stringue = NULL ; + + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT, + NULL); + + if (a_this->kind.font_face_rule->decl_list) { + stringue = (GString *) g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + if (a_indent) + cr_utils_dump_n_chars2 (' ', stringue, + a_indent); + g_string_append (stringue, "@font-face {\n"); + tmp_str = (gchar *) cr_declaration_list_to_string2 + (a_this->kind.font_face_rule->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE) ; + if (tmp_str) { + g_string_append (stringue, + tmp_str) ; + g_free (tmp_str) ; + tmp_str = NULL ; + } + g_string_append (stringue, "\n}"); + } + if (stringue) { + result = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return result ; +} + + +/** + * cr_statement_charset_to_string: + * + *Serialises an \@charset statement into a string. + *@a_this: the statement to serialize. + *@a_indent: the number of indentation spaces + * + *Returns the serialized charset statement. Must be + *freed by the caller using g_free(). + */ +static gchar * +cr_statement_charset_to_string (CRStatement const *a_this, + gulong a_indent) +{ + gchar *str = NULL ; + GString *stringue = NULL ; + + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT, + NULL) ; + + if (a_this->kind.charset_rule + && a_this->kind.charset_rule->charset + && a_this->kind.charset_rule->charset->stryng + && a_this->kind.charset_rule->charset->stryng->str) { + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + g_string_append_printf (stringue, + "@charset \"%s\" ;", + a_this->kind.charset_rule->charset->stryng->str); + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + } + return str ; +} + + +/** + * cr_statement_at_page_rule_to_string: + * + *Serialises the at page rule statement into a string + *@a_this: the current instance of #CRStatement. Must + *be an "\@page" rule statement. + * + *Returns the serialized string. Must be freed by the caller + */ +static gchar * +cr_statement_at_page_rule_to_string (CRStatement const *a_this, + gulong a_indent) +{ + GString *stringue = NULL; + gchar *result = NULL ; + + stringue = (GString *) g_string_new (NULL) ; + + cr_utils_dump_n_chars2 (' ', stringue, a_indent) ; + g_string_append (stringue, "@page"); + if (a_this->kind.page_rule->name + && a_this->kind.page_rule->name->stryng) { + g_string_append_printf + (stringue, " %s", + a_this->kind.page_rule->name->stryng->str) ; + } else { + g_string_append (stringue, " "); + } + if (a_this->kind.page_rule->pseudo + && a_this->kind.page_rule->pseudo->stryng) { + g_string_append_printf + (stringue, " :%s", + a_this->kind.page_rule->pseudo->stryng->str) ; + } + if (a_this->kind.page_rule->decl_list) { + gchar *str = NULL ; + g_string_append (stringue, " {\n"); + str = (gchar *) cr_declaration_list_to_string2 + (a_this->kind.page_rule->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + g_string_append (stringue, "\n}\n"); + } + result = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + return result ; +} + + +/** + *Serializes an \@media statement. + *@param a_this the current instance of #CRStatement + *@param a_indent the number of spaces of indentation. + *@return the serialized \@media statement. Must be freed + *by the caller using g_free(). + */ +static gchar * +cr_statement_media_rule_to_string (CRStatement const *a_this, + gulong a_indent) +{ + gchar *str = NULL ; + GString *stringue = NULL ; + GList const *cur = NULL; + + g_return_val_if_fail (a_this->type == AT_MEDIA_RULE_STMT, + NULL); + + if (a_this->kind.media_rule) { + stringue = (GString *) g_string_new (NULL) ; + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + g_string_append (stringue, "@media"); + + for (cur = a_this->kind.media_rule->media_list; cur; + cur = cur->next) { + CRString const *crstr = cur->data; + if (crstr && crstr->stryng) { + gchar const *str2 = crstr->stryng->str; + if (str2) { + if (cur->prev) { + g_string_append + (stringue, + ","); + } + g_string_append_printf + (stringue, + " %s", str2); + } + } + } + g_string_append (stringue, " {\n"); + str = cr_statement_list_to_string + (a_this->kind.media_rule->rulesets, + a_indent + DECLARATION_INDENT_NB) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + g_string_append (stringue, "\n}"); + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + } + return str ; +} + + +static gchar * +cr_statement_import_rule_to_string (CRStatement const *a_this, + gulong a_indent) +{ + GString *stringue = NULL ; + gchar *str = NULL; + + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + NULL) ; + + if (a_this->kind.import_rule->url + && a_this->kind.import_rule->url->stryng) { + stringue = (GString *) g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + if (a_this->kind.import_rule->url->stryng->str) { + g_string_append_printf (stringue, + "@import url(\"%s\")", + a_this->kind.import_rule->url->stryng->str); + } else /*there is no url, so no import rule, get out! */ + return NULL; + + if (a_this->kind.import_rule->media_list) { + GList const *cur = NULL; + + for (cur = a_this->kind.import_rule->media_list; + cur; cur = cur->next) { + if (cur->data) { + CRString const *crstr = cur->data; + + if (cur->prev) { + g_string_append + (stringue, ", "); + } + if (crstr + && crstr->stryng + && crstr->stryng->str) { + g_string_append_len + (stringue, + crstr->stryng->str, + crstr->stryng->len) ; + } + } + } + } + g_string_append (stringue, " ;"); + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return str ; +} + + +/******************* + *public functions + ******************/ + +/** + * cr_statement_does_buf_parses_against_core: + * + *@a_buf: the buffer to parse. + *@a_encoding: the character encoding of a_buf. + * + *Tries to parse a buffer and says whether if the content of the buffer + *is a css statement as defined by the "Core CSS Grammar" (chapter 4 of the + *css spec) or not. + * + *Returns TRUE if the buffer parses against the core grammar, false otherwise. + */ +gboolean +cr_statement_does_buf_parses_against_core (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRParser *parser = NULL; + enum CRStatus status = CR_OK; + gboolean result = FALSE; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + g_return_val_if_fail (parser, FALSE); + + status = cr_parser_set_use_core_grammar (parser, TRUE); + if (status != CR_OK) { + goto cleanup; + } + + status = cr_parser_parse_statement_core (parser); + if (status == CR_OK) { + result = TRUE; + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + } + + return result; +} + +/** + * cr_statement_parse_from_buf: + * + *@a_buf: the buffer to parse. + *@a_encoding: the character encoding of a_buf. + * + *Parses a buffer that contains a css statement and returns + *an instance of #CRStatement in case of successful parsing. + *TODO: at support of "\@import" rules. + * + *Returns the newly built instance of #CRStatement in case + *of successful parsing, NULL otherwise. + */ +CRStatement * +cr_statement_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding) +{ + CRStatement *result = NULL; + + /* + *The strategy of this function is "brute force". + *It tries to parse all the types of CRStatement it knows about. + *I could do this a smarter way but I don't have the time now. + *I think I will revisit this when time of performances and + *pull based incremental parsing comes. + */ + + result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding); + if (!result) { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_media_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_font_face_rule_parse_from_buf + (a_buf, a_encoding); + + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_page_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_import_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + out: + return result; +} + +/** + * cr_statement_ruleset_parse_from_buf: + * + *@a_buf: the buffer to parse. + *@a_enc: the character encoding of a_buf. + * + *Parses a buffer that contains a ruleset statement and instantiates + *a #CRStatement of type RULESET_STMT. + * + *Returns the newly built instance of #CRStatement in case of successful parsing, + *NULL otherwise. + */ +CRStatement * +cr_statement_ruleset_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_enc, FALSE); + + g_return_val_if_fail (parser, NULL); + + sac_handler = cr_doc_handler_new (); + g_return_val_if_fail (sac_handler, NULL); + + sac_handler->start_selector = parse_ruleset_start_selector_cb; + sac_handler->end_selector = parse_ruleset_end_selector_cb; + sac_handler->property = parse_ruleset_property_cb; + sac_handler->unrecoverable_error = + parse_ruleset_unrecoverable_error_cb; + + cr_parser_set_sac_handler (parser, sac_handler); + cr_parser_try_to_skip_spaces_and_comments (parser); + status = cr_parser_parse_ruleset (parser); + if (status != CR_OK) { + goto cleanup; + } + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (!((status == CR_OK) && result)) { + if (result) { + cr_statement_destroy (result); + result = NULL; + } + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + * cr_statement_new_ruleset: + * + *@a_sel_list: the list of #CRSimpleSel (selectors) + *the rule applies to. + *@a_decl_list: the list of instances of #CRDeclaration + *that composes the ruleset. + *@a_media_types: a list of instances of GString that + *describe the media list this ruleset applies to. + * + *Creates a new instance of #CRStatement of type + *#CRRulSet. + * + *Returns the new instance of #CRStatement or NULL if something + *went wrong. + */ +CRStatement * +cr_statement_new_ruleset (CRStyleSheet * a_sheet, + CRSelector * a_sel_list, + CRDeclaration * a_decl_list, + CRStatement * a_parent_media_rule) +{ + CRStatement *result = NULL; + + g_return_val_if_fail (a_sel_list, NULL); + + if (a_parent_media_rule) { + g_return_val_if_fail + (a_parent_media_rule->type == AT_MEDIA_RULE_STMT, + NULL); + g_return_val_if_fail (a_parent_media_rule->kind.media_rule, + NULL); + } + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = RULESET_STMT; + result->kind.ruleset = (CRRuleSet *) g_try_malloc (sizeof (CRRuleSet)); + + if (!result->kind.ruleset) { + cr_utils_trace_info ("Out of memory"); + if (result) + g_free (result); + return NULL; + } + + memset (result->kind.ruleset, 0, sizeof (CRRuleSet)); + result->kind.ruleset->sel_list = a_sel_list; + if (a_sel_list) + cr_selector_ref (a_sel_list); + result->kind.ruleset->decl_list = a_decl_list; + + if (a_parent_media_rule) { + result->kind.ruleset->parent_media_rule = a_parent_media_rule; + a_parent_media_rule->kind.media_rule->rulesets = + cr_statement_append + (a_parent_media_rule->kind.media_rule->rulesets, + result); + } + + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + * cr_statement_at_media_rule_parse_from_buf: + * + *@a_buf: the input to parse. + *@a_enc: the encoding of the buffer. + * + *Parses a buffer that contains an "\@media" declaration + *and builds an \@media css statement. + * + *Returns the \@media statement, or NULL if the buffer could not + *be successfully parsed. + */ +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) +{ + CRParser *parser = NULL; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + enum CRStatus status = CR_OK; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_enc, FALSE); + if (!parser) { + cr_utils_trace_info ("Instantiation of the parser failed"); + goto cleanup; + } + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) { + cr_utils_trace_info + ("Instantiation of the sac handler failed"); + goto cleanup; + } + + sac_handler->start_media = parse_at_media_start_media_cb; + sac_handler->start_selector = parse_at_media_start_selector_cb; + sac_handler->property = parse_at_media_property_cb; + sac_handler->end_selector = parse_at_media_end_selector_cb; + sac_handler->end_media = parse_at_media_end_media_cb; + sac_handler->unrecoverable_error = + parse_at_media_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_media (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (status != CR_OK) + goto cleanup; + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + + return result; +} + +/** + * cr_statement_new_at_media_rule: + * + *@a_ruleset: the ruleset statements contained + *in the \@media rule. + *@a_media: the media string list. A list of GString pointers. + * + *Instantiates an instance of #CRStatement of type + *AT_MEDIA_RULE_STMT (\@media ruleset). + * + */ +CRStatement * +cr_statement_new_at_media_rule (CRStyleSheet * a_sheet, + CRStatement * a_rulesets, GList * a_media) +{ + CRStatement *result = NULL, + *cur = NULL; + + if (a_rulesets) + g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL); + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_MEDIA_RULE_STMT; + + result->kind.media_rule = (CRAtMediaRule *) g_try_malloc (sizeof (CRAtMediaRule)); + if (!result->kind.media_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.media_rule, 0, sizeof (CRAtMediaRule)); + result->kind.media_rule->rulesets = a_rulesets; + for (cur = a_rulesets; cur; cur = cur->next) { + if (cur->type != RULESET_STMT || !cur->kind.ruleset) { + cr_utils_trace_info ("Bad parameter a_rulesets. " + "It should be a list of " + "correct ruleset statement only !"); + goto error; + } + cur->kind.ruleset->parent_media_rule = result; + } + + result->kind.media_rule->media_list = a_media; + if (a_sheet) { + cr_statement_set_parent_sheet (result, a_sheet); + } + + return result; + + error: + g_clear_pointer (&result, cr_statement_destroy); + return NULL; +} + +/** + * cr_statement_new_at_import_rule: + * + *@a_url: the url to connect to the get the file + *to be imported. + *@a_sheet: the imported parsed stylesheet. + * + *Creates a new instance of #CRStatment of type + *#CRAtImportRule. + * + *Returns the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_new_at_import_rule (CRStyleSheet * a_container_sheet, + CRString * a_url, + GList * a_media_list, + CRStyleSheet * a_imported_sheet) +{ + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_IMPORT_RULE_STMT; + + result->kind.import_rule = (CRAtImportRule *) g_try_malloc (sizeof (CRAtImportRule)); + + if (!result->kind.import_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + + memset (result->kind.import_rule, 0, sizeof (CRAtImportRule)); + result->kind.import_rule->url = a_url; + result->kind.import_rule->media_list = a_media_list; + result->kind.import_rule->sheet = a_imported_sheet; + if (a_container_sheet) + cr_statement_set_parent_sheet (result, a_container_sheet); + + return result; +} + +/** + * cr_statement_at_import_rule_parse_from_buf: + * + *@a_buf: the buffer to parse. + *@a_encoding: the encoding of a_buf. + * + *Parses a buffer that contains an "\@import" rule and + *instantiate a #CRStatement of type AT_IMPORT_RULE_STMT + * + *Returns the newly built instance of #CRStatement in case of + *a successful parsing, NULL otherwise. + */ +CRStatement * +cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRStatement *result = NULL; + GList *media_list = NULL; + CRString *import_string = NULL; + CRParsingLocation location = {0,0,0} ; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instantiation of parser failed."); + goto cleanup; + } + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_import (parser, + &media_list, + &import_string, + &location); + if (status != CR_OK || !import_string) + goto cleanup; + + result = cr_statement_new_at_import_rule (NULL, import_string, + media_list, NULL); + if (result) { + cr_parsing_location_copy (&result->location, + &location) ; + import_string = NULL; + media_list = NULL; + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (media_list) { + for (; media_list; + media_list = g_list_next (media_list)) { + if (media_list->data) { + cr_string_destroy ((CRString*)media_list->data); + media_list->data = NULL; + } + } + g_list_free (media_list); + media_list = NULL; + } + if (import_string) { + cr_string_destroy (import_string); + import_string = NULL; + } + + return result; +} + +/** + * cr_statement_new_at_page_rule: + * + *@a_decl_list: a list of instances of #CRDeclarations + *which is actually the list of declarations that applies to + *this page rule. + *@a_selector: the page rule selector. + * + *Creates a new instance of #CRStatement of type + *#CRAtPageRule. + * + *Returns the newly built instance of #CRStatement or NULL + *in case of error. + */ +CRStatement * +cr_statement_new_at_page_rule (CRStyleSheet * a_sheet, + CRDeclaration * a_decl_list, + CRString * a_name, CRString * a_pseudo) +{ + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_PAGE_RULE_STMT; + + result->kind.page_rule = (CRAtPageRule *) g_try_malloc (sizeof (CRAtPageRule)); + + if (!result->kind.page_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + + memset (result->kind.page_rule, 0, sizeof (CRAtPageRule)); + if (a_decl_list) { + result->kind.page_rule->decl_list = a_decl_list; + cr_declaration_ref (a_decl_list); + } + result->kind.page_rule->name = a_name; + result->kind.page_rule->pseudo = a_pseudo; + if (a_sheet) + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + * cr_statement_at_page_rule_parse_from_buf: + * + *@a_buf: the character buffer to parse. + *@a_encoding: the character encoding of a_buf. + * + *Parses a buffer that contains an "\@page" production and, + *if the parsing succeeds, builds the page statement. + * + *Returns the newly built at page statement in case of successful parsing, + *NULL otherwise. + */ +CRStatement * +cr_statement_at_page_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instantiation of the parser failed."); + goto cleanup; + } + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) { + cr_utils_trace_info + ("Instantiation of the sac handler failed."); + goto cleanup; + } + + sac_handler->start_page = parse_page_start_page_cb; + sac_handler->property = parse_page_property_cb; + sac_handler->end_page = parse_page_end_page_cb; + sac_handler->unrecoverable_error = parse_page_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + /*Now, invoke the parser to parse the "@page production" */ + cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + status = cr_parser_parse_page (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + * cr_statement_new_at_charset_rule: + * + *@a_charset: the string representing the charset. + *Note that the newly built instance of #CRStatement becomes + *the owner of a_charset. The caller must not free a_charset !!!. + * + *Creates a new instance of #CRStatement of type + *#CRAtCharsetRule. + * + *Returns the newly built instance of #CRStatement or NULL + *if an error arises. + */ +CRStatement * +cr_statement_new_at_charset_rule (CRStyleSheet * a_sheet, + CRString * a_charset) +{ + CRStatement *result = NULL; + + g_return_val_if_fail (a_charset, NULL); + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_CHARSET_RULE_STMT; + + result->kind.charset_rule = (CRAtCharsetRule *) g_try_malloc (sizeof (CRAtCharsetRule)); + + if (!result->kind.charset_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule)); + result->kind.charset_rule->charset = a_charset; + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + * cr_statement_at_charset_rule_parse_from_buf: + * + *@a_buf: the buffer to parse. + *@a_encoding: the character encoding of the buffer. + * + *Parses a buffer that contains an '\@charset' rule and + *creates an instance of #CRStatement of type AT_CHARSET_RULE_STMT. + * + *Returns the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_at_charset_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRStatement *result = NULL; + CRString *charset = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instantiation of the parser failed."); + goto cleanup; + } + + /*Now, invoke the parser to parse the "@charset production" */ + cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + status = cr_parser_parse_charset (parser, &charset, NULL); + if (status != CR_OK || !charset) + goto cleanup; + + result = cr_statement_new_at_charset_rule (NULL, charset); + if (result) + charset = NULL; + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (charset) { + cr_string_destroy (charset); + } + + return result; +} + +/** + * cr_statement_new_at_font_face_rule: + * + *@a_font_decls: a list of instances of #CRDeclaration. Each declaration + *is actually a font declaration. + * + *Creates an instance of #CRStatement of type #CRAtFontFaceRule. + * + *Returns the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_new_at_font_face_rule (CRStyleSheet * a_sheet, + CRDeclaration * a_font_decls) +{ + CRStatement *result = NULL; + + result = (CRStatement *) g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRStatement)); + result->type = AT_FONT_FACE_RULE_STMT; + + result->kind.font_face_rule = (CRAtFontFaceRule *) g_try_malloc + (sizeof (CRAtFontFaceRule)); + + if (!result->kind.font_face_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.font_face_rule, 0, sizeof (CRAtFontFaceRule)); + + result->kind.font_face_rule->decl_list = a_font_decls; + if (a_sheet) + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + * cr_statement_font_face_rule_parse_from_buf: + * + * + *@a_buf: the buffer to parse. + *@a_encoding: the character encoding of a_buf. + * + *Parses a buffer that contains an "\@font-face" rule and builds + *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it. + * + *Returns the newly built instance of #CRStatement in case of successufull + *parsing, NULL otherwise. + */ +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + enum CRStatus status = CR_OK; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + if (!parser) + goto cleanup; + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) + goto cleanup; + + /* + *set sac callbacks here + */ + sac_handler->start_font_face = parse_font_face_start_font_face_cb; + sac_handler->property = parse_font_face_property_cb; + sac_handler->end_font_face = parse_font_face_end_font_face_cb; + sac_handler->unrecoverable_error = + parse_font_face_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + /* + *cleanup spaces of comment that may be there before the real + *"@font-face" thing. + */ + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_font_face (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (status != CR_OK || !result) + goto cleanup; + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + * cr_statement_set_parent_sheet: + * + *@a_this: the current instance of #CRStatement. + *@a_sheet: the sheet that contains the current statement. + * + *Sets the container stylesheet. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_set_parent_sheet (CRStatement * a_this, CRStyleSheet * a_sheet) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + a_this->parent_sheet = a_sheet; + return CR_OK; +} + +/** + * cr_statement_get_parent_sheet: + * + *@a_this: the current #CRStatement. + *@a_sheet: out parameter. A pointer to the sheets that + * + *Gets the sheets that contains the current statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_get_parent_sheet (CRStatement * a_this, CRStyleSheet ** a_sheet) +{ + g_return_val_if_fail (a_this && a_sheet, CR_BAD_PARAM_ERROR); + *a_sheet = a_this->parent_sheet; + return CR_OK; +} + +/** + * cr_statement_append: + * + *@a_this: the current instance of the statement list. + *@a_new: a_new the new instance of #CRStatement to append. + * + *Appends a new statement to the statement list. + * + *Returns the new list statement list, or NULL in case of failure. + */ +CRStatement * +cr_statement_append (CRStatement * a_this, CRStatement * a_new) +{ + CRStatement *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) { + return a_new; + } + + /*walk forward in the current list to find the tail list element */ + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + * cr_statement_prepend: + * + *@a_this: the current instance of #CRStatement. + *@a_new: the new statement to prepend. + * + *Prepends the an instance of #CRStatement to + *the current statement list. + * + *Returns the new list with the new statement prepended, + *or NULL in case of an error. + */ +CRStatement * +cr_statement_prepend (CRStatement * a_this, CRStatement * a_new) +{ + CRStatement *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + a_new->next = a_this; + a_this->prev = a_new; + + /*walk backward in the prepended list to find the head list element */ + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + * cr_statement_unlink: + * + *@a_this: the current statements list. + *@a_to_unlink: the statement to unlink from the list. + * + *Unlinks a statement from the statements list. + * + *Returns the new list where a_to_unlink has been unlinked + *from, or NULL in case of error. + */ +CRStatement * +cr_statement_unlink (CRStatement * a_stmt) +{ + CRStatement *result = a_stmt; + + g_return_val_if_fail (result, NULL); + + /** + *Some sanity checks first + */ + if (a_stmt->next) { + g_return_val_if_fail (a_stmt->next->prev == a_stmt, NULL); + } + if (a_stmt->prev) { + g_return_val_if_fail (a_stmt->prev->next == a_stmt, NULL); + } + + /** + *Now, the real unlinking job. + */ + if (a_stmt->next) { + a_stmt->next->prev = a_stmt->prev; + } + if (a_stmt->prev) { + a_stmt->prev->next = a_stmt->next; + } + + if (a_stmt->parent_sheet + && a_stmt->parent_sheet->statements == a_stmt) { + a_stmt->parent_sheet->statements = + a_stmt->parent_sheet->statements->next; + } + + a_stmt->next = NULL; + a_stmt->prev = NULL; + a_stmt->parent_sheet = NULL; + + return result; +} + +/** + * cr_statement_nr_rules: + * + *@a_this: the current instance of #CRStatement. + * + *Gets the number of rules in the statement list; + * + *Returns number of rules in the statement list. + */ +gint +cr_statement_nr_rules (CRStatement const * a_this) +{ + CRStatement const *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, -1); + + for (cur = a_this; cur; cur = cur->next) + nr++; + return nr; +} + +/** + * cr_statement_get_from_list: + * + *@a_this: the current instance of #CRStatement. + *@itemnr: the index into the statement list. + * + *Use an index to get a CRStatement from the statement list. + * + *Returns CRStatement at position itemnr, if itemnr > number of statements - 1, + *it will return NULL. + */ +CRStatement * +cr_statement_get_from_list (CRStatement * a_this, int itemnr) +{ + CRStatement *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, NULL); + + for (cur = a_this; cur; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + * cr_statement_ruleset_set_sel_list: + * + *@a_this: the current ruleset statement. + *@a_sel_list: the selector list to set. Note + *that this function increments the ref count of a_sel_list. + *The sel list will be destroyed at the destruction of the + *current instance of #CRStatement. + * + *Sets a selector list to a ruleset statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_set_sel_list (CRStatement * a_this, + CRSelector * a_sel_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.ruleset->sel_list) + cr_selector_unref (a_this->kind.ruleset->sel_list); + + a_this->kind.ruleset->sel_list = a_sel_list; + + if (a_sel_list) + cr_selector_ref (a_sel_list); + + return CR_OK; +} + +/** + * cr_statement_ruleset_get_declarations: + * + *@a_this: the current instance of #CRStatement. + *@a_decl_list: out parameter. A pointer to the returned + *list of declaration. Must not be NULL. + * + *Gets a pointer to the list of declaration contained + *in the ruleset statement. + * + *Returns CR_OK upon successful completion, an error code if something + *bad happened. + */ +enum CRStatus +cr_statement_ruleset_get_declarations (CRStatement * a_this, + CRDeclaration ** a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == RULESET_STMT + && a_this->kind.ruleset + && a_decl_list, CR_BAD_PARAM_ERROR); + + *a_decl_list = a_this->kind.ruleset->decl_list; + + return CR_OK; +} + +/** + * cr_statement_ruleset_get_sel_list: + * + *@a_this: the current ruleset statement. + *@a_list: out parameter. The returned selector list, + *if and only if the function returned CR_OK. + * + *Gets a pointer to the selector list contained in + *the current ruleset statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_get_sel_list (CRStatement const * a_this, CRSelector ** a_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + *a_list = a_this->kind.ruleset->sel_list; + + return CR_OK; +} + +/** + * cr_statement_ruleset_set_decl_list: + * + *@a_this: the current ruleset statement. + *@a_list: the declaration list to be added to the current + *ruleset statement. + * + *Sets a declaration list to the current ruleset statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_set_decl_list (CRStatement * a_this, + CRDeclaration * a_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + if (a_this->kind.ruleset->decl_list == a_list) + return CR_OK; + + if (a_this->kind.ruleset->sel_list) { + cr_declaration_destroy (a_this->kind.ruleset->decl_list); + } + + a_this->kind.ruleset->sel_list = NULL; + + return CR_OK; +} + +/** + * cr_statement_ruleset_append_decl2: + * + *@a_this: the current statement. + *@a_prop: the property of the declaration. + *@a_value: the value of the declaration. + * + *Appends a declaration to the current ruleset statement. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_statement_ruleset_append_decl2 (CRStatement * a_this, + CRString * a_prop, + CRTerm * a_value) +{ + CRDeclaration *new_decls = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + new_decls = cr_declaration_append2 + (a_this->kind.ruleset->decl_list, + a_prop, a_value); + g_return_val_if_fail (new_decls, CR_ERROR); + a_this->kind.ruleset->decl_list = new_decls; + + return CR_OK; +} + +/** + * cr_statement_ruleset_append_decl: + * + *Appends a declaration to the current statement. + * + *@a_this: the current statement. + *@a_declaration: the declaration to append. + * + *Returns CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_statement_ruleset_append_decl (CRStatement * a_this, + CRDeclaration * a_decl) +{ + CRDeclaration *new_decls = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + new_decls = cr_declaration_append + (a_this->kind.ruleset->decl_list, a_decl); + g_return_val_if_fail (new_decls, CR_ERROR); + a_this->kind.ruleset->decl_list = new_decls; + + return CR_OK; +} + +/** + * cr_statement_at_import_rule_set_imported_sheet: + * + *Sets a stylesheet to the current \@import rule. + *@a_this: the current \@import rule. + *@a_sheet: the stylesheet. The stylesheet is owned + *by the current instance of #CRStatement, that is, the + *stylesheet will be destroyed when the current instance + *of #CRStatement is destroyed. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_set_imported_sheet (CRStatement * a_this, + CRStyleSheet * a_sheet) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + a_this->kind.import_rule->sheet = a_sheet; + + return CR_OK; +} + +/** + * cr_statement_at_import_rule_get_imported_sheet: + * + *@a_this: the current \@import rule statement. + *@a_sheet: out parameter. The returned stylesheet if and + *only if the function returns CR_OK. + * + *Gets the stylesheet contained by the \@import rule statement. + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_get_imported_sheet (CRStatement * a_this, + CRStyleSheet ** a_sheet) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + *a_sheet = a_this->kind.import_rule->sheet; + return CR_OK; + +} + +/** + * cr_statement_at_import_rule_set_url: + * + *@a_this: the current \@import rule statement. + *@a_url: the url to set. + * + *Sets an url to the current \@import rule statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_set_url (CRStatement * a_this, + CRString * a_url) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.import_rule->url) { + cr_string_destroy (a_this->kind.import_rule->url); + } + + a_this->kind.import_rule->url = a_url; + + return CR_OK; +} + +/** + * cr_statement_at_import_rule_get_url: + * + *@a_this: the current \@import rule statement. + *@a_url: out parameter. The returned url if + *and only if the function returned CR_OK. + * + *Gets the url of the \@import rule statement. + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_get_url (CRStatement const * a_this, + CRString ** a_url) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + *a_url = a_this->kind.import_rule->url; + + return CR_OK; +} + +/** + * cr_statement_at_media_nr_rules: + * + *@a_this: the current instance of #CRStatement. + * + *Returns the number of rules in the media rule; + */ +int +cr_statement_at_media_nr_rules (CRStatement const * a_this) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_MEDIA_RULE_STMT + && a_this->kind.media_rule, CR_BAD_PARAM_ERROR); + + return cr_statement_nr_rules (a_this->kind.media_rule->rulesets); +} + +/** + * cr_statement_at_media_get_from_list: + * + *@a_this: the current instance of #CRStatement. + *@itemnr: the index into the media rule list of rules. + * + *Use an index to get a CRStatement from the media rule list of rules. + * + *Returns CRStatement at position itemnr, if itemnr > number of rules - 1, + *it will return NULL. + */ +CRStatement * +cr_statement_at_media_get_from_list (CRStatement * a_this, int itemnr) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_MEDIA_RULE_STMT + && a_this->kind.media_rule, NULL); + + return cr_statement_get_from_list (a_this->kind.media_rule->rulesets, + itemnr); +} + +/** + * cr_statement_at_page_rule_set_declarations: + * + *@a_this: the current \@page rule statement. + *@a_decl_list: the declaration list to add. Will be freed + *by the current instance of #CRStatement when it is destroyed. + * + *Sets a declaration list to the current \@page rule statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_page_rule_set_declarations (CRStatement * a_this, + CRDeclaration * a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule, CR_BAD_PARAM_ERROR); + + if (a_this->kind.page_rule->decl_list) { + cr_declaration_unref (a_this->kind.page_rule->decl_list); + } + + a_this->kind.page_rule->decl_list = a_decl_list; + + if (a_decl_list) { + cr_declaration_ref (a_decl_list); + } + + return CR_OK; +} + +/** + * cr_statement_at_page_rule_get_declarations: + * + *@a_this: the current \@page rule statement. + *@a_decl_list: out parameter. The returned declaration list. + * + *Gets the declaration list associated to the current \@page rule + *statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_page_rule_get_declarations (CRStatement * a_this, + CRDeclaration ** a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule, CR_BAD_PARAM_ERROR); + + *a_decl_list = a_this->kind.page_rule->decl_list; + + return CR_OK; +} + +/** + * cr_statement_at_charset_rule_set_charset: + * + * + *@a_this: the current \@charset rule statement. + *@a_charset: the charset to set. + * + *Sets the charset of the current \@charset rule statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_charset_rule_set_charset (CRStatement * a_this, + CRString * a_charset) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT + && a_this->kind.charset_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.charset_rule->charset) { + cr_string_destroy (a_this->kind.charset_rule->charset); + } + a_this->kind.charset_rule->charset = a_charset; + return CR_OK; +} + +/** + * cr_statement_at_charset_rule_get_charset: + *@a_this: the current \@charset rule statement. + *@a_charset: out parameter. The returned charset string if + *and only if the function returned CR_OK. + * + *Gets the charset string associated to the current + *\@charset rule statement. + * + * Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_charset_rule_get_charset (CRStatement const * a_this, + CRString ** a_charset) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT + && a_this->kind.charset_rule, + CR_BAD_PARAM_ERROR); + + *a_charset = a_this->kind.charset_rule->charset; + + return CR_OK; +} + +/** + * cr_statement_at_font_face_rule_set_decls: + * + *@a_this: the current \@font-face rule statement. + *@a_decls: the declarations list to set. + * + *Sets a declaration list to the current \@font-face rule statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_set_decls (CRStatement * a_this, + CRDeclaration * a_decls) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.font_face_rule->decl_list) { + cr_declaration_unref (a_this->kind.font_face_rule->decl_list); + } + + a_this->kind.font_face_rule->decl_list = a_decls; + cr_declaration_ref (a_decls); + + return CR_OK; +} + +/** + * cr_statement_at_font_face_rule_get_decls: + * + *@a_this: the current \@font-face rule statement. + *@a_decls: out parameter. The returned declaration list if + *and only if this function returns CR_OK. + * + *Gets the declaration list associated to the current instance + *of \@font-face rule statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_get_decls (CRStatement * a_this, + CRDeclaration ** a_decls) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + *a_decls = a_this->kind.font_face_rule->decl_list; + + return CR_OK; +} + +/** + * cr_statement_at_font_face_rule_add_decl: + * + *@a_this: the current \@font-face rule statement. + *@a_prop: the property of the declaration. + *@a_value: the value of the declaration. + * + *Adds a declaration to the current \@font-face rule + *statement. + * + *Returns CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_add_decl (CRStatement * a_this, + CRString * a_prop, CRTerm * a_value) +{ + CRDeclaration *decls = NULL; + + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + decls = cr_declaration_append2 + (a_this->kind.font_face_rule->decl_list, + a_prop, a_value); + + g_return_val_if_fail (decls, CR_ERROR); + + if (a_this->kind.font_face_rule->decl_list == NULL) + cr_declaration_ref (decls); + + a_this->kind.font_face_rule->decl_list = decls; + + return CR_OK; +} + + +/** + * cr_statement_to_string: + * + *@a_this: the current statement to serialize + *@a_indent: the number of white space of indentation. + * + *Serializes a css statement into a string + * + *Returns the serialized statement. Must be freed by the caller + *using g_free(). + */ +gchar * +cr_statement_to_string (CRStatement const * a_this, gulong a_indent) +{ + gchar *str = NULL ; + + if (!a_this) + return NULL; + + switch (a_this->type) { + case RULESET_STMT: + str = cr_statement_ruleset_to_string + (a_this, a_indent); + break; + + case AT_FONT_FACE_RULE_STMT: + str = cr_statement_font_face_rule_to_string + (a_this, a_indent) ; + break; + + case AT_CHARSET_RULE_STMT: + str = cr_statement_charset_to_string + (a_this, a_indent); + break; + + case AT_PAGE_RULE_STMT: + str = cr_statement_at_page_rule_to_string + (a_this, a_indent); + break; + + case AT_MEDIA_RULE_STMT: + str = cr_statement_media_rule_to_string + (a_this, a_indent); + break; + + case AT_IMPORT_RULE_STMT: + str = cr_statement_import_rule_to_string + (a_this, a_indent); + break; + + default: + cr_utils_trace_info ("Statement unrecognized"); + break; + } + return str ; +} + +gchar* +cr_statement_list_to_string (CRStatement const *a_this, gulong a_indent) +{ + CRStatement const *cur_stmt = NULL ; + GString *stringue = NULL ; + gchar *str = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + stringue = g_string_new (NULL) ; + if (!stringue) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + for (cur_stmt = a_this ; cur_stmt; + cur_stmt = cur_stmt->next) { + str = cr_statement_to_string (cur_stmt, a_indent) ; + if (str) { + if (!cur_stmt->prev) { + g_string_append (stringue, str) ; + } else { + g_string_append_printf + (stringue, "\n%s", str) ; + } + g_free (str) ; + str = NULL ; + } + } + str = stringue->str ; + g_string_free (stringue, FALSE) ; + return str ; +} + +/** + * cr_statement_dump: + * + *@a_this: the current css2 statement. + *@a_fp: the destination file pointer. + *@a_indent: the number of white space indentation characters. + * + *Dumps the css2 statement to a file. + */ +void +cr_statement_dump (CRStatement const * a_this, FILE * a_fp, gulong a_indent) +{ + gchar *str = NULL ; + + if (!a_this) + return; + + str = cr_statement_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, "%s",str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + * cr_statement_dump_ruleset: + * + *@a_this: the current instance of #CRStatement. + *@a_fp: the destination file pointer. + *@a_indent: the number of indentation white spaces to add. + * + *Dumps a ruleset statement to a file. + */ +void +cr_statement_dump_ruleset (CRStatement const * a_this, FILE * a_fp, glong a_indent) +{ + gchar *str = NULL; + + g_return_if_fail (a_fp && a_this); + str = cr_statement_ruleset_to_string (a_this, a_indent); + if (str) { + fprintf (a_fp, "%s", str); + g_free (str); + str = NULL; + } +} + +/** + * cr_statement_dump_font_face_rule: + * + *@a_this: the current instance of font face rule statement. + *@a_fp: the destination file pointer. + *@a_indent: the number of white space indentation. + * + *Dumps a font face rule statement to a file. + */ +void +cr_statement_dump_font_face_rule (CRStatement const * a_this, FILE * a_fp, + glong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT); + + str = cr_statement_font_face_rule_to_string (a_this, + a_indent) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + * cr_statement_dump_charset: + * + *@a_this: the current instance of the \@charset rule statement. + *@a_fp: the destination file pointer. + *@a_indent: the number of indentation white spaces. + * + *Dumps an \@charset rule statement to a file. + */ +void +cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, gulong a_indent) +{ + gchar *str = NULL; + + g_return_if_fail (a_this && a_this->type == AT_CHARSET_RULE_STMT); + + str = cr_statement_charset_to_string (a_this, + a_indent) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + + +/** + * cr_statement_dump_page: + * + *@a_this: the statement to dump on stdout. + *@a_fp: the destination file pointer. + *@a_indent: the number of indentation white spaces. + * + *Dumps an \@page rule statement on stdout. + */ +void +cr_statement_dump_page (CRStatement const * a_this, FILE * a_fp, gulong a_indent) +{ + gchar *str = NULL; + + g_return_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule); + + str = cr_statement_at_page_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, "%s", str); + g_free (str) ; + str = NULL ; + } +} + + +/** + * cr_statement_dump_media_rule: + * + *@a_this: the statement to dump. + *@a_fp: the destination file pointer + *@a_indent: the number of white spaces indentation. + * + *Dumps an \@media rule statement to a file. + */ +void +cr_statement_dump_media_rule (CRStatement const * a_this, + FILE * a_fp, + gulong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this->type == AT_MEDIA_RULE_STMT); + + str = cr_statement_media_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + * cr_statement_dump_import_rule: + * + *@a_fp: the destination file pointer. + *@a_indent: the number of white space indentations. + * + *Dumps an \@import rule statement to a file. + */ +void +cr_statement_dump_import_rule (CRStatement const * a_this, FILE * a_fp, + gulong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_fp + && a_this->kind.import_rule); + + str = cr_statement_import_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + * cr_statement_destroy: + * + * @a_this: the current instance of #CRStatement. + * + *Destructor of #CRStatement. + */ +void +cr_statement_destroy (CRStatement * a_this) +{ + CRStatement *cur = NULL; + + g_return_if_fail (a_this); + + /*go get the tail of the list */ + for (cur = a_this; cur && cur->next; cur = cur->next) { + cr_statement_clear (cur); + } + + if (cur) + cr_statement_clear (cur); + + if (cur->prev == NULL) { + g_free (a_this); + return; + } + + /*walk backward and free next element */ + for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + } + + if (!cur) + return; + + /*free the one remaining list */ + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + + g_free (cur); + cur = NULL; +} diff --git a/src/3rdparty/libcroco/src/cr-statement.h b/src/3rdparty/libcroco/src/cr-statement.h new file mode 100644 index 0000000..06538d0 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-statement.h @@ -0,0 +1,440 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <stdio.h> +#include "cr-utils.h" +#include "cr-term.h" +#include "cr-selector.h" +#include "cr-declaration.h" + +#ifndef __CR_STATEMENT_H__ +#define __CR_STATEMENT_H__ + +G_BEGIN_DECLS + +/** + *@file + *Declaration of the #CRStatement class. + */ + +/* + *forward declaration of CRStyleSheet which is defined in + *cr-stylesheet.h + */ + +struct _CRStatement ; + +/* + *typedef struct _CRStatement CRStatement ; + *this is forward declared in + *cr-declaration.h already. + */ + +struct _CRAtMediaRule ; +typedef struct _CRAtMediaRule CRAtMediaRule ; + +typedef struct _CRRuleSet CRRuleSet ; + +/** + *The abstraction of a css ruleset. + *A ruleset is made of a list of selectors, + *followed by a list of declarations. + */ +struct _CRRuleSet +{ + /**A list of instances of #CRSimpeSel*/ + CRSelector *sel_list ; + + /**A list of instances of #CRDeclaration*/ + CRDeclaration *decl_list ; + + /** + *The parent media rule, or NULL if + *no parent media rule exists. + */ + CRStatement *parent_media_rule ; +} ; + +/* + *a forward declaration of CRStylesheet. + *CRStylesheet is actually declared in + *cr-stylesheet.h + */ +struct _CRStyleSheet ; +typedef struct _CRStyleSheet CRStyleSheet; + + +/**The \@import rule abstraction.*/ +typedef struct _CRAtImportRule CRAtImportRule ; +struct _CRAtImportRule +{ + /**the url of the import rule*/ + CRString *url ; + + GList *media_list ; + + /** + *the stylesheet fetched from the url, if any. + *this is not "owned" by #CRAtImportRule which means + *it is not destroyed by the destructor of #CRAtImportRule. + */ + CRStyleSheet * sheet; +}; + + +/**abstraction of an \@media rule*/ +struct _CRAtMediaRule +{ + GList *media_list ; + CRStatement *rulesets ; +} ; + + +typedef struct _CRAtPageRule CRAtPageRule ; +/**The \@page rule abstraction*/ +struct _CRAtPageRule +{ + /**a list of instances of #CRDeclaration*/ + CRDeclaration *decl_list ; + + /**page selector. Is a pseudo selector*/ + CRString *name ; + CRString *pseudo ; +} ; + +/**The \@charset rule abstraction*/ +typedef struct _CRAtCharsetRule CRAtCharsetRule ; +struct _CRAtCharsetRule +{ + CRString * charset ; +}; + +/**The abstraction of the \@font-face rule.*/ +typedef struct _CRAtFontFaceRule CRAtFontFaceRule ; +struct _CRAtFontFaceRule +{ + /*a list of instanaces of #CRDeclaration*/ + CRDeclaration *decl_list ; +} ; + + +/** + *The possible types of css2 statements. + */ +enum CRStatementType +{ + /** + *A generic css at-rule + *each unknown at-rule will + *be of this type. + */ + + /**A css at-rule*/ + AT_RULE_STMT = 0, + + /*A css ruleset*/ + RULESET_STMT, + + /**A css2 import rule*/ + AT_IMPORT_RULE_STMT, + + /**A css2 media rule*/ + AT_MEDIA_RULE_STMT, + + /**A css2 page rule*/ + AT_PAGE_RULE_STMT, + + /**A css2 charset rule*/ + AT_CHARSET_RULE_STMT, + + /**A css2 font face rule*/ + AT_FONT_FACE_RULE_STMT +} ; + + +/** + *The abstraction of css statement as defined + *in the chapter 4 and appendix D.1 of the css2 spec. + *A statement is actually a double chained list of + *statements.A statement can be a ruleset, an \@import + *rule, an \@page rule etc ... + */ +struct _CRStatement +{ + /** + *The type of the statement. + */ + enum CRStatementType type ; + + union + { + CRRuleSet *ruleset ; + CRAtImportRule *import_rule ; + CRAtMediaRule *media_rule ; + CRAtPageRule *page_rule ; + CRAtCharsetRule *charset_rule ; + CRAtFontFaceRule *font_face_rule ; + } kind ; + + /* + *the specificity of the selector + *that matched this statement. + *This is only used by the cascading + *order determination algorithm. + */ + gulong specificity ; + + /* + *the style sheet that contains + *this css statement. + */ + CRStyleSheet *parent_sheet ; + CRStatement *next ; + CRStatement *prev ; + + CRParsingLocation location ; + + /** + *a custom pointer usable by + *applications that use libcroco. + *libcroco itself will never modify + *this pointer. + */ + gpointer app_data ; + + /** + *a custom pointer used + *by the upper layers of libcroco. + *application should never use this + *pointer. + */ + gpointer croco_data ; + +} ; + + +gboolean +cr_statement_does_buf_parses_against_core (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRStatement * +cr_statement_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRStatement* +cr_statement_new_ruleset (CRStyleSheet *a_sheet, + CRSelector *a_sel_list, + CRDeclaration *a_decl_list, + CRStatement *a_media_rule) ; +CRStatement * +cr_statement_ruleset_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) ; + +CRStatement* +cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet, + CRString *a_url, + GList *a_media_list, + CRStyleSheet *a_imported_sheet) ; + +CRStatement * +cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) ; + +CRStatement * +cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, + CRStatement *a_ruleset, + GList *a_media) ; +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_enc) ; + +CRStatement * +cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, + CRString *a_charset) ; +CRStatement * +cr_statement_at_charset_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding); + + +CRStatement * +cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_font_decls) ; +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; + +CRStatement * +cr_statement_new_at_page_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_decl_list, + CRString *a_name, + CRString *a_pseudo) ; +CRStatement * +cr_statement_at_page_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; + +enum CRStatus +cr_statement_set_parent_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; + +enum CRStatus +cr_statement_get_parent_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; + +CRStatement * +cr_statement_append (CRStatement *a_this, + CRStatement *a_new) ; + +CRStatement* +cr_statement_prepend (CRStatement *a_this, + CRStatement *a_new) ; + +CRStatement * +cr_statement_unlink (CRStatement *a_stmt) ; + +enum CRStatus +cr_statement_ruleset_set_sel_list (CRStatement *a_this, + CRSelector *a_sel_list) ; + +enum CRStatus +cr_statement_ruleset_get_sel_list (CRStatement const *a_this, + CRSelector **a_list) ; + +enum CRStatus +cr_statement_ruleset_set_decl_list (CRStatement *a_this, + CRDeclaration *a_list) ; + +enum CRStatus +cr_statement_ruleset_get_declarations (CRStatement *a_this, + CRDeclaration **a_decl_list) ; + +enum CRStatus +cr_statement_ruleset_append_decl2 (CRStatement *a_this, + CRString *a_prop, CRTerm *a_value) ; + +enum CRStatus +cr_statement_ruleset_append_decl (CRStatement *a_this, + CRDeclaration *a_decl) ; + +enum CRStatus +cr_statement_at_import_rule_set_imported_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; + +enum CRStatus +cr_statement_at_import_rule_get_imported_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; + +enum CRStatus +cr_statement_at_import_rule_set_url (CRStatement *a_this, + CRString *a_url) ; + +enum CRStatus +cr_statement_at_import_rule_get_url (CRStatement const *a_this, + CRString **a_url) ; + +gint +cr_statement_at_media_nr_rules (CRStatement const *a_this) ; + +CRStatement * +cr_statement_at_media_get_from_list (CRStatement *a_this, int itemnr) ; + +enum CRStatus +cr_statement_at_page_rule_set_sel (CRStatement *a_this, + CRSelector *a_sel) ; + +enum CRStatus +cr_statement_at_page_rule_get_sel (CRStatement const *a_this, + CRSelector **a_sel) ; + +enum CRStatus +cr_statement_at_page_rule_set_declarations (CRStatement *a_this, + CRDeclaration *a_decl_list) ; + +enum CRStatus +cr_statement_at_page_rule_get_declarations (CRStatement *a_this, + CRDeclaration **a_decl_list) ; + +enum CRStatus +cr_statement_at_charset_rule_set_charset (CRStatement *a_this, + CRString *a_charset) ; + +enum CRStatus +cr_statement_at_charset_rule_get_charset (CRStatement const *a_this, + CRString **a_charset) ; + +enum CRStatus +cr_statement_at_font_face_rule_set_decls (CRStatement *a_this, + CRDeclaration *a_decls) ; + +enum CRStatus +cr_statement_at_font_face_rule_get_decls (CRStatement *a_this, + CRDeclaration **a_decls) ; + +enum CRStatus +cr_statement_at_font_face_rule_add_decl (CRStatement *a_this, + CRString *a_prop, + CRTerm *a_value) ; + +gchar * +cr_statement_to_string (CRStatement const * a_this, gulong a_indent) ; + +gchar* +cr_statement_list_to_string (CRStatement const *a_this, gulong a_indent) ; + +void +cr_statement_dump (CRStatement const *a_this, FILE *a_fp, gulong a_indent) ; + +void +cr_statement_dump_ruleset (CRStatement const * a_this, FILE * a_fp, + glong a_indent) ; + +void +cr_statement_dump_font_face_rule (CRStatement const * a_this, + FILE * a_fp, + glong a_indent) ; + +void +cr_statement_dump_page (CRStatement const * a_this, FILE * a_fp, + gulong a_indent) ; + + +void +cr_statement_dump_media_rule (CRStatement const * a_this, + FILE * a_fp, + gulong a_indent) ; + +void +cr_statement_dump_import_rule (CRStatement const * a_this, FILE * a_fp, + gulong a_indent) ; +void +cr_statement_dump_charset (CRStatement const * a_this, FILE * a_fp, + gulong a_indent) ; +gint +cr_statement_nr_rules (CRStatement const *a_this) ; + +CRStatement * +cr_statement_get_from_list (CRStatement *a_this, int itemnr) ; + +void +cr_statement_destroy (CRStatement *a_this) ; + +G_END_DECLS + +#endif /*__CR_STATEMENT_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-string.c b/src/3rdparty/libcroco/src/cr-string.c new file mode 100644 index 0000000..ec5840e --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-string.c @@ -0,0 +1,170 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + +#include <string.h> +#include "cr-string.h" + +/** + *Instantiates a #CRString + *@return the newly instantiated #CRString + *Must be freed with cr_string_destroy(). + */ +CRString * +cr_string_new (void) +{ + CRString *result = NULL ; + + result = (CRString *) g_try_malloc (sizeof (CRString)) ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + memset (result, 0, sizeof (CRString)) ; + result->stryng = g_string_new (NULL) ; + return result ; +} + +/** + *Instantiate a string and initialise it to + *a_string. + *@param a_string the initial string + *@return the newly instantiated string. + */ +CRString * +cr_string_new_from_string (const gchar * a_string) +{ + CRString *result = NULL ; + + result = cr_string_new () ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + if (a_string) + g_string_append (result->stryng, a_string) ; + return result ; +} + +/** + *Instantiates a #CRString from an instance of GString. + *@param a_string the input string that will be copied into + *the newly instantiated #CRString + *@return the newly instantiated #CRString. + */ +CRString * +cr_string_new_from_gstring (GString const *a_string) +{ + CRString *result = NULL ; + + result = cr_string_new () ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + if (a_string) { + g_string_append_len (result->stryng, + a_string->str, + a_string->len); + + } + return result ; +} + +CRString * +cr_string_dup (CRString const *a_this) +{ + CRString *result = NULL ; + g_return_val_if_fail (a_this, NULL) ; + + result = cr_string_new_from_gstring (a_this->stryng) ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + cr_parsing_location_copy (&result->location, + &a_this->location) ; + return result ; +} + +gchar * +cr_string_dup2 (CRString const *a_this) +{ + gchar *result = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + if (a_this + && a_this->stryng + && a_this->stryng->str) { + result = g_strndup (a_this->stryng->str, + a_this->stryng->len) ; + } + return result ; +} + +/** + *Returns a pointer to the internal raw NULL terminated string + *of the current instance of #CRString. + *@param a_this the current instance of #CRString + */ +const gchar * +cr_string_peek_raw_str (CRString const *a_this) +{ + g_return_val_if_fail (a_this, NULL) ; + + if (a_this->stryng && a_this->stryng->str) + return a_this->stryng->str ; + return NULL ; +} + +/** + *Returns the length of the internal raw NULL terminated + *string of the current instance of #CRString. + *@param a_this the current instance of #CRString. + *@return the len of the internal raw NULL termninated string, + *of -1 if no length can be returned. + */ +gint +cr_string_peek_raw_str_len (CRString const *a_this) +{ + g_return_val_if_fail (a_this && a_this->stryng, + -1) ; + return a_this->stryng->len ; +} + +/** + *@param a_this the #CRString to destroy. + */ +void +cr_string_destroy (CRString *a_this) +{ + if (!a_this) { + return; + } + + if (a_this->stryng) { + g_string_free (a_this->stryng, TRUE) ; + a_this->stryng = NULL ; + } + g_free (a_this) ; +} diff --git a/src/3rdparty/libcroco/src/cr-string.h b/src/3rdparty/libcroco/src/cr-string.h new file mode 100644 index 0000000..2700f0e --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-string.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +/** + *@file + *Declaration file of the #CRString class. + */ + +#ifndef __CR_STRING_H__ +#define __CR_STRING_H__ + +#include <glib.h> +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +typedef struct _CRString CRString ; + +/** + *This is a ship implementation of string based on GString. + *Actually, the aim of CRString is to store the parsing location + *(line,column,byte offset) at which a given string has been parsed + *in the input CSS. + *So this class has a gstring field of type GString that users can + *freely manipulate, and also a CRParginLocation type where the + *parsing location is store. If you don't want to deal with parsing + *location stuffs, then use GString instead. If we were in C++ for example, + *CRString would just inherit GString and just add accessors to + *the CRParsingLocation data ... but we are not and we still have + *to provide the parsing location information. + */ +struct _CRString { + /** + *The GString where all the string + *operation happen. + */ + GString *stryng ; + /** + *The parsing location storage area. + */ + CRParsingLocation location ; +} ; + +CRString * cr_string_new (void) ; + +CRString *cr_string_new_from_string (const gchar * a_string) ; +CRString * cr_string_new_from_gstring (GString const *a_string) ; +CRString *cr_string_dup (CRString const *a_this) ; +gchar *cr_string_dup2 (CRString const *a_this) ; +const gchar *cr_string_peek_raw_str (CRString const *a_this) ; +gint cr_string_peek_raw_str_len (CRString const *a_this) ; +void cr_string_destroy (CRString *a_this) ; + +G_END_DECLS + +#endif diff --git a/src/3rdparty/libcroco/src/cr-style.c b/src/3rdparty/libcroco/src/cr-style.c new file mode 100644 index 0000000..9653c50 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-style.c @@ -0,0 +1,2852 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * see COPYRIGHTS file for copyright information + */ + +#include <string.h> +#include "cr-style.h" + +/** + *@file + *The definition of the #CRStyle class. + */ + +/** + *A property ID. + *Each supported css property has an ID which is + *an entry into a property "population" jump table. + *each entry of the property population jump table + *contains code to transform the literal form of + *a property value into a strongly typed value. + */ +enum CRPropertyID { + PROP_ID_NOT_KNOWN = 0, + PROP_ID_PADDING_TOP, + PROP_ID_PADDING_RIGHT, + PROP_ID_PADDING_BOTTOM, + PROP_ID_PADDING_LEFT, + PROP_ID_PADDING, + PROP_ID_BORDER_TOP_WIDTH, + PROP_ID_BORDER_RIGHT_WIDTH, + PROP_ID_BORDER_BOTTOM_WIDTH, + PROP_ID_BORDER_LEFT_WIDTH, + PROP_ID_BORDER_WIDTH, + PROP_ID_BORDER_TOP_STYLE, + PROP_ID_BORDER_RIGHT_STYLE, + PROP_ID_BORDER_BOTTOM_STYLE, + PROP_ID_BORDER_LEFT_STYLE, + PROP_ID_BORDER_STYLE, + PROP_ID_BORDER_TOP_COLOR, + PROP_ID_BORDER_RIGHT_COLOR, + PROP_ID_BORDER_BOTTOM_COLOR, + PROP_ID_BORDER_LEFT_COLOR, + PROP_ID_BORDER_TOP, + PROP_ID_BORDER_RIGHT, + PROP_ID_BORDER_BOTTOM, + PROP_ID_BORDER_LEFT, + PROP_ID_BORDER, + PROP_ID_MARGIN_TOP, + PROP_ID_MARGIN_RIGHT, + PROP_ID_MARGIN_BOTTOM, + PROP_ID_MARGIN_LEFT, + PROP_ID_MARGIN, + PROP_ID_DISPLAY, + PROP_ID_POSITION, + PROP_ID_TOP, + PROP_ID_RIGHT, + PROP_ID_BOTTOM, + PROP_ID_LEFT, + PROP_ID_FLOAT, + PROP_ID_WIDTH, + PROP_ID_COLOR, + PROP_ID_BACKGROUND_COLOR, + PROP_ID_FONT_FAMILY, + PROP_ID_FONT_SIZE, + PROP_ID_FONT_STYLE, + PROP_ID_FONT_WEIGHT, + PROP_ID_WHITE_SPACE, + /*should be the last one. */ + NB_PROP_IDS +}; + +typedef struct _CRPropertyDesc CRPropertyDesc; + +struct _CRPropertyDesc { + const gchar *name; + enum CRPropertyID prop_id; +}; + +static CRPropertyDesc gv_prop_table[] = { + {"padding-top", PROP_ID_PADDING_TOP}, + {"padding-right", PROP_ID_PADDING_RIGHT}, + {"padding-bottom", PROP_ID_PADDING_BOTTOM}, + {"padding-left", PROP_ID_PADDING_LEFT}, + {"padding", PROP_ID_PADDING}, + {"border-top-width", PROP_ID_BORDER_TOP_WIDTH}, + {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH}, + {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH}, + {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH}, + {"border-width", PROP_ID_BORDER_WIDTH}, + {"border-top-style", PROP_ID_BORDER_TOP_STYLE}, + {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE}, + {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE}, + {"border-left-style", PROP_ID_BORDER_LEFT_STYLE}, + {"border-style", PROP_ID_BORDER_STYLE}, + {"border-top", PROP_ID_BORDER_TOP}, + {"border-right", PROP_ID_BORDER_RIGHT}, + {"border-bottom", PROP_ID_BORDER_BOTTOM}, + {"border-left", PROP_ID_BORDER_LEFT}, + {"border", PROP_ID_BORDER}, + {"margin-top", PROP_ID_MARGIN_TOP}, + {"margin-right", PROP_ID_MARGIN_RIGHT}, + {"margin-bottom", PROP_ID_MARGIN_BOTTOM}, + {"margin-left", PROP_ID_MARGIN_LEFT}, + {"margin", PROP_ID_MARGIN}, + {"display", PROP_ID_DISPLAY}, + {"position", PROP_ID_POSITION}, + {"top", PROP_ID_TOP}, + {"right", PROP_ID_RIGHT}, + {"bottom", PROP_ID_BOTTOM}, + {"left", PROP_ID_LEFT}, + {"float", PROP_ID_FLOAT}, + {"width", PROP_ID_WIDTH}, + {"color", PROP_ID_COLOR}, + {"border-top-color", PROP_ID_BORDER_TOP_COLOR}, + {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR}, + {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR}, + {"border-left-color", PROP_ID_BORDER_LEFT_COLOR}, + {"background-color", PROP_ID_BACKGROUND_COLOR}, + {"font-family", PROP_ID_FONT_FAMILY}, + {"font-size", PROP_ID_FONT_SIZE}, + {"font-style", PROP_ID_FONT_STYLE}, + {"font-weight", PROP_ID_FONT_WEIGHT}, + {"white-space", PROP_ID_WHITE_SPACE}, + /*must be the last one */ + {NULL, (enum CRPropertyID) 0} +}; + +/** + *A the key/value pair of this hash table + *are: + *key => name of the css property found in gv_prop_table + *value => matching property id found in gv_prop_table. + *So this hash table is here just to retrieval of a property id + *from a property name. + */ +static GHashTable *gv_prop_hash = NULL; + +/** + *incremented by each new instance of #CRStyle + *and decremented at the it destroy time. + *When this reaches zero, gv_prop_hash is destroyed. + */ +static gulong gv_prop_hash_ref_count = 0; + +struct CRNumPropEnumDumpInfo { + enum CRNumProp code; + const gchar *str; +}; + +static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = { + {NUM_PROP_TOP, "top"}, + {NUM_PROP_RIGHT, "right"}, + {NUM_PROP_BOTTOM, "bottom"}, + {NUM_PROP_LEFT, "left"}, + {NUM_PROP_PADDING_TOP, "padding-top"}, + {NUM_PROP_PADDING_RIGHT, "padding-right"}, + {NUM_PROP_PADDING_BOTTOM, "padding-bottom"}, + {NUM_PROP_PADDING_LEFT, "padding-left"}, + {NUM_PROP_BORDER_TOP, "border-top"}, + {NUM_PROP_BORDER_RIGHT, "border-right"}, + {NUM_PROP_BORDER_BOTTOM, "border-bottom"}, + {NUM_PROP_BORDER_LEFT, "border-left"}, + {NUM_PROP_MARGIN_TOP, "margin-top"}, + {NUM_PROP_MARGIN_RIGHT, "margin-right"}, + {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"}, + {NUM_PROP_MARGIN_LEFT, "margin-left"}, + {NUM_PROP_WIDTH, "width"}, + {(enum CRNumProp) 0, NULL} +}; + +struct CRRgbPropEnumDumpInfo { + enum CRRgbProp code; + const gchar *str; +}; + +static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = { + {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"}, + {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"}, + {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"}, + {RGB_PROP_BORDER_LEFT_COLOR, "left-color"}, + {RGB_PROP_COLOR, "color"}, + {RGB_PROP_BACKGROUND_COLOR, "background-color"}, + {(enum CRRgbProp) 0, NULL} +}; + +struct CRBorderStylePropEnumDumpInfo { + enum CRBorderStyleProp code; + const gchar *str; + +}; + +static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[] + = { + {BORDER_STYLE_PROP_TOP, "border-style-top"}, + {BORDER_STYLE_PROP_RIGHT, "border-style-right"}, + {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"}, + {BORDER_STYLE_PROP_LEFT, "border-style-left"}, + {(enum CRBorderStyleProp) 0, NULL} +}; + +static enum CRStatus + cr_style_init_properties (void); + +enum CRDirection { + DIR_TOP = 0, + DIR_RIGHT, + DIR_BOTTOM, + DIR_LEFT, + + /*must be the last one */ + NB_DIRS +}; + +static const gchar *num_prop_code_to_string (enum CRNumProp a_code); + +static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code); + +static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp + a_code); + +static enum CRStatus +set_prop_padding_x_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_x_width_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir); +static enum CRStatus +set_prop_border_width_from_value (CRStyle *a_style, + CRTerm *a_value) ; + +static enum CRStatus +set_prop_border_x_style_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir); +static enum CRStatus +set_prop_border_style_from_value (CRStyle *a_style, + CRTerm *a_value) ; + +static enum CRStatus +set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_float (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_width (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_color (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_background_color (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +init_style_font_size_field (CRStyle * a_style); + +static enum CRStatus +set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value); + +static const gchar * +num_prop_code_to_string (enum CRNumProp a_code) +{ + guint len = sizeof (gv_num_props_dump_infos) / + sizeof (struct CRNumPropEnumDumpInfo); + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRNumProp' and no matching" + " entry has been " + "added to gv_num_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_num_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRNumProp' and " + "the order of entries in " + "the gv_num_prop_dump_infos table"); + return NULL; + } + return gv_num_props_dump_infos[a_code].str; +} + +static const gchar * +rgb_prop_code_to_string (enum CRRgbProp a_code) +{ + guint len = sizeof (gv_rgb_props_dump_infos) / + sizeof (struct CRRgbPropEnumDumpInfo); + + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRRgbProp' and no matching" + " entry has been " + "added to gv_rgb_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_rgb_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRRgbProp' and " + "the order of entries in " + "the gv_rgb_props_dump_infos table"); + return NULL; + } + return gv_rgb_props_dump_infos[a_code].str; +} + +static const gchar * +border_style_prop_code_to_string (enum CRBorderStyleProp a_code) +{ + guint len = sizeof (gv_border_style_props_dump_infos) / + sizeof (struct CRBorderStylePropEnumDumpInfo); + + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRBorderStyleProp' and no matching" + " entry has been " + "added to gv_border_style_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_border_style_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRBorderStyleProp' and " + "the order of entries in " + "the gv_border_style_props_dump_infos table"); + return NULL; + } + return gv_border_style_props_dump_infos[a_code].str; +} + +static enum CRStatus +cr_style_init_properties (void) +{ + + if (!gv_prop_hash) { + gulong i = 0; + + gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal); + if (!gv_prop_hash) { + cr_utils_trace_info ("Out of memory"); + return CR_ERROR; + } + + /*load gv_prop_hash from gv_prop_table */ + for (i = 0; gv_prop_table[i].name; i++) { + g_hash_table_insert + (gv_prop_hash, + (gpointer) gv_prop_table[i].name, + GINT_TO_POINTER (gv_prop_table[i].prop_id)); + } + } + + return CR_OK; +} + +static enum CRPropertyID +cr_style_get_prop_id (const guchar * a_prop) +{ + gpointer *raw_id = NULL; + + if (!gv_prop_hash) { + cr_style_init_properties (); + } + + raw_id = (gpointer *) g_hash_table_lookup (gv_prop_hash, a_prop); + if (!raw_id) { + return PROP_ID_NOT_KNOWN; + } + return (enum CRPropertyID)GPOINTER_TO_INT (raw_id); +} + +static enum CRStatus +set_prop_padding_x_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT) + return CR_BAD_PARAM_ERROR; + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strncmp ((const char *) "inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + status = cr_num_set (num_val, 0.0, NUM_INHERIT); + return CR_OK; + } else + return CR_UNKNOWN_TYPE_ERROR; + } + + g_return_val_if_fail (a_value->type == TERM_NUMBER + && a_value->content.num, CR_UNKNOWN_TYPE_ERROR); + + switch (a_value->content.num->type) { + case NUM_LENGTH_EM: + case NUM_LENGTH_EX: + case NUM_LENGTH_PX: + case NUM_LENGTH_IN: + case NUM_LENGTH_CM: + case NUM_LENGTH_MM: + case NUM_LENGTH_PT: + case NUM_LENGTH_PC: + case NUM_PERCENTAGE: + status = cr_num_copy (num_val, a_value->content.num); + break; + default: + status = CR_UNKNOWN_TYPE_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_border_x_width_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv; + break; + + default: + return CR_BAD_PARAM_ERROR; + break; + } + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("thin", + a_value->content.str->stryng->str, + sizeof ("thin")-1)) { + cr_num_set (num_val, BORDER_THIN, + NUM_LENGTH_PX); + } else if (!strncmp + ("medium", + a_value->content.str->stryng->str, + sizeof ("medium")-1)) { + cr_num_set (num_val, BORDER_MEDIUM, + NUM_LENGTH_PX); + } else if (!strncmp ("thick", + a_value->content.str->stryng->str, + sizeof ("thick")-1)) { + cr_num_set (num_val, BORDER_THICK, + NUM_LENGTH_PX); + } else { + return CR_UNKNOWN_TYPE_ERROR; + } + } + } else if (a_value->type == TERM_NUMBER) { + if (a_value->content.num) { + cr_num_copy (num_val, a_value->content.num); + } + } else if (a_value->type != TERM_NUMBER + || a_value->content.num == NULL) { + return CR_UNKNOWN_TYPE_ERROR; + } + + return status; +} + +static enum CRStatus +set_prop_border_width_from_value (CRStyle *a_style, + CRTerm *a_value) +{ + CRTerm *cur_term = NULL ; + int dir; + + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR) ; + cur_term = a_value ; + + if (!cur_term) + return CR_ERROR ; + + for (dir = (int) DIR_TOP ; dir < (int)NB_DIRS ; dir++) { + enum CRDirection direction = (enum CRDirection)dir; + set_prop_border_x_width_from_value (a_style, + cur_term, + direction) ; + } + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_RIGHT) ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_LEFT) ; + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_BOTTOM) ; + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_LEFT) ; + + return CR_OK ; +} + +static enum CRStatus +set_prop_border_x_style_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + enum CRBorderStyle *border_style_ptr = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_TOP]; + break; + + case DIR_RIGHT: + border_style_ptr = + &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT]; + break; + + case DIR_BOTTOM: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_BOTTOM]; + break; + + case DIR_LEFT: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_LEFT]; + break; + + default: + break; + } + + if (a_value->type != TERM_IDENT || !a_value->content.str) { + return CR_UNKNOWN_TYPE_ERROR; + } + + if (!strncmp ("none", + a_value->content.str->stryng->str, + sizeof ("none")-1)) { + *border_style_ptr = BORDER_STYLE_NONE; + } else if (!strncmp ("hidden", + a_value->content.str->stryng->str, + sizeof ("hidden")-1)) { + *border_style_ptr = BORDER_STYLE_HIDDEN; + } else if (!strncmp ("dotted", + a_value->content.str->stryng->str, + sizeof ("dotted")-1)) { + *border_style_ptr = BORDER_STYLE_DOTTED; + } else if (!strncmp ("dashed", + a_value->content.str->stryng->str, sizeof ("dashed")-1)) { + *border_style_ptr = BORDER_STYLE_DASHED; + } else if (!strncmp ("solid", + a_value->content.str->stryng->str, sizeof ("solid")-1)) { + *border_style_ptr = BORDER_STYLE_SOLID; + } else if (!strncmp ("double", + a_value->content.str->stryng->str, sizeof ("double")-1)) { + *border_style_ptr = BORDER_STYLE_DOUBLE; + } else if (!strncmp ("groove", + a_value->content.str->stryng->str, sizeof ("groove")-1)) { + *border_style_ptr = BORDER_STYLE_GROOVE; + } else if (!strncmp ("ridge", + a_value->content.str->stryng->str, + sizeof ("ridge")-1)) { + *border_style_ptr = BORDER_STYLE_RIDGE; + } else if (!strncmp ("inset", + a_value->content.str->stryng->str, + sizeof ("inset")-1)) { + *border_style_ptr = BORDER_STYLE_INSET; + } else if (!strncmp ("outset", + a_value->content.str->stryng->str, + sizeof ("outset")-1)) { + *border_style_ptr = BORDER_STYLE_OUTSET; + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + *border_style_ptr = BORDER_STYLE_INHERIT; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + + return status; +} + +static enum CRStatus +set_prop_border_style_from_value (CRStyle *a_style, + CRTerm *a_value) +{ + CRTerm *cur_term = NULL ; + int dir; + + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR) ; + + cur_term = a_value ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_ERROR ; + } + + for (dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++) { + enum CRDirection direction = (enum CRDirection)dir; + set_prop_border_x_style_from_value (a_style, + cur_term, + direction) ; + } + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_RIGHT) ; + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_LEFT) ; + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_BOTTOM) ; + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_LEFT) ; + return CR_OK ; +} + +static enum CRStatus +set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv; + break; + + default: + break; + } + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "inherit")) { + status = cr_num_set (num_val, 0.0, NUM_INHERIT); + } else if (a_value->content.str + && a_value->content.str->stryng + && !strcmp (a_value->content.str->stryng->str, + "auto")) { + status = cr_num_set (num_val, 0.0, NUM_AUTO); + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + break ; + + case TERM_NUMBER: + status = cr_num_copy (num_val, a_value->content.num); + break; + + default: + status = CR_UNKNOWN_TYPE_ERROR; + break; + } + + return status; +} + +struct CRPropDisplayValPair { + const gchar *prop_name; + enum CRDisplayType type; +}; + +static enum CRStatus +set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value) +{ + static const struct CRPropDisplayValPair disp_vals_map[] = { + {"none", DISPLAY_NONE}, + {"inline", DISPLAY_INLINE}, + {"block", DISPLAY_BLOCK}, + {"run-in", DISPLAY_RUN_IN}, + {"compact", DISPLAY_COMPACT}, + {"marker", DISPLAY_MARKER}, + {"table", DISPLAY_TABLE}, + {"inline-table", DISPLAY_INLINE_TABLE}, + {"table-row-group", DISPLAY_TABLE_ROW_GROUP}, + {"table-header-group", DISPLAY_TABLE_HEADER_GROUP}, + {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP}, + {"table-row", DISPLAY_TABLE_ROW}, + {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP}, + {"table-column", DISPLAY_TABLE_COLUMN}, + {"table-cell", DISPLAY_TABLE_CELL}, + {"table-caption", DISPLAY_TABLE_CAPTION}, + {"inherit", DISPLAY_INHERIT}, + {NULL, DISPLAY_NONE} + }; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + { + int i = 0; + + if (!a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) + break; + + for (i = 0; disp_vals_map[i].prop_name; i++) { + if (!strncmp + (disp_vals_map[i].prop_name, + a_value->content.str->stryng->str, + strlen (disp_vals_map[i].prop_name))) { + a_style->display = + disp_vals_map[i].type; + break; + } + } + } + break; + + default: + break; + } + + return CR_OK; +} + +struct CRPropPositionValPair { + const gchar *name; + enum CRPositionType type; +}; + +static enum CRStatus +set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR; + static const struct CRPropPositionValPair position_vals_map[] = { + {"static", POSITION_STATIC}, + {"relative", POSITION_RELATIVE}, + {"absolute", POSITION_ABSOLUTE}, + {"fixed", POSITION_FIXED}, + {"inherit", POSITION_INHERIT}, + {NULL, POSITION_STATIC} + /*must alwas be the last one */ + }; + + g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + { + int i = 0; + + if (!a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) + break; + + for (i = 0; position_vals_map[i].name; i++) { + if (!strncmp (position_vals_map[i].name, + a_value->content.str->stryng->str, + strlen (position_vals_map[i]. + name))) { + a_style->position = + position_vals_map[i].type; + status = CR_OK; + break; + } + } + } + break; + + default: + break; + } + + return status; +} + +static enum CRStatus +set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRNum *box_offset = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (!(a_value->type == TERM_NUMBER) + && !(a_value->type == TERM_IDENT)) { + return CR_UNKNOWN_PROP_VAL_ERROR; + } + + switch (a_dir) { + case DIR_TOP: + box_offset = &a_style->num_props[NUM_PROP_TOP].sv; + break; + + case DIR_RIGHT: + box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv; + break; + + case DIR_BOTTOM: + box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv; + break; + case DIR_LEFT: + box_offset = &a_style->num_props[NUM_PROP_LEFT].sv; + break; + + default: + break; + } + + box_offset->type = NUM_AUTO; + + if (a_value->type == TERM_NUMBER && a_value->content.num) { + cr_num_copy (box_offset, a_value->content.num); + } else if (a_value->type == TERM_IDENT + && a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + cr_num_set (box_offset, 0.0, NUM_INHERIT); + } else if (!strncmp ("auto", + a_value->content.str->stryng->str, + sizeof ("auto")-1)) { + box_offset->type = NUM_AUTO; + } + } + + return CR_OK; +} + +static enum CRStatus +set_prop_float (CRStyle * a_style, CRTerm * a_value) +{ + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR); + + /*the default float type as specified by the css2 spec */ + a_style->float_type = FLOAT_NONE; + + if (a_value->type != TERM_IDENT + || !a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) { + /*unknown type, the float type is set to it's default value */ + return CR_OK; + } + + if (!strncmp ("none", + a_value->content.str->stryng->str, + sizeof ("none")-1)) { + a_style->float_type = FLOAT_NONE; + } else if (!strncmp ("left", + a_value->content.str->stryng->str, + sizeof ("left")-1)) { + a_style->float_type = FLOAT_LEFT; + } else if (!strncmp ("right", + a_value->content.str->stryng->str, + sizeof ("right")-1)) { + a_style->float_type = FLOAT_RIGHT; + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + a_style->float_type = FLOAT_INHERIT; + } + return CR_OK; +} + +static enum CRStatus +set_prop_width (CRStyle * a_style, CRTerm * a_value) +{ + CRNum *width = NULL; + g_return_val_if_fail (a_style + && a_value, + CR_BAD_PARAM_ERROR); + + width = &a_style->num_props[NUM_PROP_WIDTH].sv; + cr_num_set (width, 0.0, NUM_AUTO); + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("auto", + a_value->content.str->stryng->str, + sizeof ("auto")-1)) { + cr_num_set (width, 0.0, NUM_AUTO); + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + cr_num_set (width, 0.0, NUM_INHERIT); + } + } + } else if (a_value->type == TERM_NUMBER) { + if (a_value->content.num) { + cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv, + a_value->content.num); + } + } + return CR_OK; +} + +static enum CRStatus +set_prop_color (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv; + + g_return_val_if_fail (a_style + && a_value, CR_BAD_PARAM_ERROR); + + status = cr_rgb_set_from_term (a_rgb, a_value); + + return status; +} + +static enum CRStatus +set_prop_background_color (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + status = cr_rgb_set_from_term (rgb, a_value); + return status; +} + +/** + *Sets border-top-color, border-right-color, + *border-bottom-color or border-left-color properties + *in the style structure. The value is taken from a + *css2 term of type IDENT or RGB. + *@param a_style the style structure to set. + *@param a_value the css2 term to take the color information from. + *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM). + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRRgb *rgb_color = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv; + break; + + case DIR_RIGHT: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv; + break; + + case DIR_BOTTOM: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv; + break; + + case DIR_LEFT: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv; + break; + + default: + cr_utils_trace_info ("unknown DIR type"); + return CR_BAD_PARAM_ERROR; + } + + status = CR_UNKNOWN_PROP_VAL_ERROR; + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + status = cr_rgb_set_from_name + (rgb_color, + (const guchar *) a_value->content.str->stryng->str); + + } + if (status != CR_OK) { + cr_rgb_set_from_name (rgb_color, (const guchar *) "black"); + } + } else if (a_value->type == TERM_RGB) { + if (a_value->content.rgb) { + status = cr_rgb_set_from_rgb + (rgb_color, a_value->content.rgb); + } + } + return status; +} + +static enum CRStatus +set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRTerm *cur_term = NULL; + + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + for (cur_term = a_value; + cur_term; + cur_term = cur_term->next) { + status = set_prop_border_x_width_from_value (a_style, + cur_term, a_dir); + + if (status != CR_OK) { + status = set_prop_border_x_style_from_value + (a_style, cur_term, a_dir); + } + if (status != CR_OK) { + status = set_prop_border_x_color_from_value + (a_style, cur_term, a_dir); + } + } + return CR_OK; +} + +static enum CRStatus +set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value) +{ + int dir; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + for (dir = 0; dir < (int)NB_DIRS; dir++) { + set_prop_border_x_from_value (a_style, + a_value, + (enum CRDirection)dir); + } + + return CR_OK; +} + +static enum CRStatus +set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + int dir; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + cur_term = a_value; + + /*filter the eventual non NUMBER terms some user can have written here*/ + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_ERROR ; + + for (dir = 0; dir < (int)NB_DIRS; dir++) { + set_prop_padding_x_from_value (a_style, + cur_term, (enum CRDirection)dir); + } + cur_term = cur_term->next; + + /*filter non NUMBER terms that some users can have written here...*/ + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + /*the user can have just written padding: 1px*/ + if (!cur_term) + return CR_OK; + + set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT); + set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT); + return status; +} + +static enum CRStatus +set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + int dir; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + cur_term = a_value; + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + + if (!cur_term) + return CR_OK; + + for (dir = 0; dir < (int)NB_DIRS; dir++) { + set_prop_margin_x_from_value(a_style, + cur_term, (enum CRDirection)dir); + } + cur_term = cur_term->next; + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT); + set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); + + return status; +} + +static enum CRStatus +set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + CRFontFamily *font_family = NULL, + *cur_ff = NULL, + *cur_ff2 = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (a_value->type == TERM_IDENT && + a_value->content.str && + a_value->content.str->stryng && + a_value->content.str->stryng->str && + !strcmp ("inherit", a_value->content.str->stryng->str)) + { + font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL); + goto out; + } + + for (cur_term = a_value; cur_term; cur_term = cur_term->next) { + switch (cur_term->type) { + case TERM_IDENT: + { + enum CRFontFamilyType font_type; + + if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp + (cur_term->content.str->stryng->str, + "sans-serif")) { + font_type = FONT_FAMILY_SANS_SERIF; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp + (cur_term->content.str->stryng->str, + "serif")) { + font_type = FONT_FAMILY_SERIF; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "cursive")) { + font_type = FONT_FAMILY_CURSIVE; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "fantasy")) { + font_type = FONT_FAMILY_FANTASY; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "monospace")) { + font_type = FONT_FAMILY_MONOSPACE; + } else { + /* + *unknown property value. + *ignore it. + */ + continue; + } + + cur_ff = cr_font_family_new (font_type, NULL); + } + break; + + case TERM_STRING: + { + if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str) { + cur_ff = cr_font_family_new + (FONT_FAMILY_NON_GENERIC, + (guchar *) cur_term->content.str->stryng->str); + } + } + break; + + default: + break; + } + + cur_ff2 = cr_font_family_append (font_family, cur_ff); + if (cur_ff2) { + font_family = cur_ff2; + } + } + + out: + if (font_family) { + if (a_style->font_family) { + cr_font_family_destroy (a_style->font_family); + a_style->font_family = NULL ; + } + a_style->font_family = font_family; + font_family = NULL ; + } + + return CR_OK; +} + +static enum CRStatus +init_style_font_size_field (CRStyle * a_style) +{ + g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR); + + memset (&a_style->font_size, 0, + sizeof (CRFontSizeVal)) ; + /* + if (!a_style->font_size) { + a_style->font_size = cr_font_size_new (); + if (!a_style->font_size) { + return CR_INSTANCIATION_FAILED_ERROR; + } + } else { + cr_font_size_clear (a_style->font_size); + } + */ + return CR_OK; +} + +static enum CRStatus +set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "xx-small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_XX_SMALL; + + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "x-small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_X_SMALL; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_SMALL; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, "medium")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_MEDIUM; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "x-large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_X_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "xx-large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_XX_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "larger")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = RELATIVE_FONT_SIZE; + a_style->font_size.sv.value.relative = FONT_SIZE_LARGER; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "smaller")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = RELATIVE_FONT_SIZE; + a_style->font_size.sv.value.relative = + FONT_SIZE_SMALLER; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, "inherit")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + a_style->font_size.sv.type = INHERITED_FONT_SIZE; + + } else { + cr_utils_trace_info ("Unknown value of font-size") ; + status = init_style_font_size_field (a_style); + return CR_UNKNOWN_PROP_VAL_ERROR; + } + break; + + case TERM_NUMBER: + if (a_value->content.num) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE; + cr_num_copy (&a_style->font_size.sv.value.absolute, + a_value->content.num) ; + } + break; + + default: + status = init_style_font_size_field (a_style); + return CR_UNKNOWN_PROP_VAL_ERROR; + } + return CR_OK; +} + +static enum CRStatus +set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strcmp (a_value->content.str->stryng->str, "normal")) { + a_style->font_style = FONT_STYLE_NORMAL; + } else if (!strcmp + (a_value->content.str->stryng->str, + "italic")) { + a_style->font_style = FONT_STYLE_ITALIC; + } else if (!strcmp + (a_value->content.str->stryng->str, + "oblique")) { + a_style->font_style = FONT_STYLE_OBLIQUE; + } else if (!strcmp + (a_value->content.str->stryng->str, + "inherit")) { + a_style->font_style = FONT_STYLE_INHERIT; + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + } + break; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strcmp (a_value->content.str->stryng->str, + "normal")) { + a_style->font_weight = FONT_WEIGHT_NORMAL; + } else if (!strcmp (a_value->content.str->stryng->str, + "bold")) { + a_style->font_weight = FONT_WEIGHT_BOLD; + } else if (!strcmp (a_value->content.str->stryng->str, + "bolder")) { + a_style->font_weight = FONT_WEIGHT_BOLDER; + } else if (!strcmp (a_value->content.str->stryng->str, + "lighter")) { + a_style->font_weight = FONT_WEIGHT_LIGHTER; + } else if (!strcmp (a_value->content.str->stryng->str, + "inherit")) { + a_style->font_weight = FONT_WEIGHT_INHERIT; + + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + + } + break; + + case TERM_NUMBER: + if (a_value->content.num + && (a_value->content.num->type == NUM_GENERIC + || a_value->content.num->type == NUM_AUTO)) { + if (a_value->content.num->val <= 150) { + a_style->font_weight = FONT_WEIGHT_100; + } else if (a_value->content.num->val <= 250) { + a_style->font_weight = FONT_WEIGHT_200; + } else if (a_value->content.num->val <= 350) { + a_style->font_weight = FONT_WEIGHT_300; + } else if (a_value->content.num->val <= 450) { + a_style->font_weight = FONT_WEIGHT_400; + } else if (a_value->content.num->val <= 550) { + a_style->font_weight = FONT_WEIGHT_500; + } else if (a_value->content.num->val <= 650) { + a_style->font_weight = FONT_WEIGHT_600; + } else if (a_value->content.num->val <= 750) { + a_style->font_weight = FONT_WEIGHT_700; + } else if (a_value->content.num->val <= 850) { + a_style->font_weight = FONT_WEIGHT_800; + } else { + a_style->font_weight = FONT_WEIGHT_900; + } + } + break; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str && a_value->content.str->stryng) { + if (!strcmp (a_value->content.str->stryng->str, "normal")) { + a_style->white_space = WHITE_SPACE_NORMAL; + } else if (!strcmp (a_value->content.str->stryng->str, + "pre")) { + a_style->white_space = WHITE_SPACE_PRE; + } else if (!strcmp (a_value->content.str->stryng->str, + "nowrap")) { + a_style->white_space = WHITE_SPACE_NOWRAP; + } else if (!strcmp (a_value->content.str->stryng->str, + "inherit")) { + a_style->white_space = WHITE_SPACE_INHERIT; + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + } + break; + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +/****************** + *Public methods + ******************/ + +/** + *Default constructor of #CRStyle. + *@param a_set_props_to_initial_values if TRUE, the style properties + *will be set to the default values. Only the style properties of the + *root box should be set to their initial values. + *Otherwise, the style values are set to their default value. + *Read the CSS2 spec, chapters 6.1.1 to 6.2. + */ +CRStyle * +cr_style_new (gboolean a_set_props_to_initial_values) +{ + CRStyle *result = NULL; + + result = (CRStyle *) g_try_malloc (sizeof (CRStyle)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRStyle)); + gv_prop_hash_ref_count++; + + if (a_set_props_to_initial_values == TRUE) { + cr_style_set_props_to_initial_values (result); + } else { + cr_style_set_props_to_default_values (result); + } + + return result; +} + +/** + *Sets the style properties to their default values according to the css2 spec + * i.e inherit if the property is inherited, its initial value otherwise. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_props_to_default_values (CRStyle * a_this) +{ + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (i = 0; i < NB_NUM_PROPS; i++) + { + switch (i) + { + case NUM_PROP_WIDTH: + case NUM_PROP_TOP: + case NUM_PROP_RIGHT: + case NUM_PROP_BOTTOM: + case NUM_PROP_LEFT: + cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); + break; + + case NUM_PROP_PADDING_TOP: + case NUM_PROP_PADDING_RIGHT: + case NUM_PROP_PADDING_BOTTOM: + case NUM_PROP_PADDING_LEFT: + case NUM_PROP_BORDER_TOP: + case NUM_PROP_BORDER_RIGHT: + case NUM_PROP_BORDER_BOTTOM: + case NUM_PROP_BORDER_LEFT: + case NUM_PROP_MARGIN_TOP: + case NUM_PROP_MARGIN_RIGHT: + case NUM_PROP_MARGIN_BOTTOM: + case NUM_PROP_MARGIN_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_LENGTH_PX); + break; + + default: + cr_utils_trace_info ("Unknown property"); + break; + } + } + + for (i = 0; i < NB_RGB_PROPS; i++) { + + switch (i) { + /*default foreground color is black */ + case RGB_PROP_COLOR: + /* + *REVIEW: color is inherited and the default value is + *ua dependent. + */ + cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv, + TRUE) ; + break; + + /*default background color is white */ + case RGB_PROP_BACKGROUND_COLOR: + /* TODO: the default value should be transparent */ + cr_rgb_set (&a_this->rgb_props[i].sv, + 255, 255, 255, FALSE); + cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, + TRUE) ; + break; + + default: + /* + *TODO: for BORDER_COLOR the initial value should + * be the same as COLOR + */ + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, + FALSE); + break; + } + } + + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + a_this->border_style_props[i] = BORDER_STYLE_NONE; + } + + a_this->display = DISPLAY_INLINE; + a_this->position = POSITION_STATIC; + a_this->float_type = FLOAT_NONE; + a_this->parent_style = NULL; + a_this->font_style = FONT_STYLE_INHERIT; + a_this->font_variant = FONT_VARIANT_INHERIT; + a_this->font_weight = FONT_WEIGHT_INHERIT; + a_this->font_family = NULL; + + cr_font_size_set_to_inherit (&a_this->font_size.sv) ; + cr_font_size_clear (&a_this->font_size.cv) ; + cr_font_size_clear (&a_this->font_size.av) ; + + /* To make the inheritance resolution possible and efficient */ + a_this->inherited_props_resolved = FALSE ; + return CR_OK; +} + +/** + *Sets the style properties to their initial value according to the css2 spec. + *This function should be used to initialize the style of the root element + *of an xml tree. + *Some properties are user agent dependent like font-family, and + *are not initialized, read the spec to make you renderer compliant. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_props_to_initial_values (CRStyle *a_this) +{ + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (i = 0; i < NB_NUM_PROPS; i++) { + switch (i) { + case NUM_PROP_WIDTH: + cr_num_set (&a_this->num_props[i].sv, 800, + NUM_LENGTH_PX) ; + break ; + case NUM_PROP_TOP: + case NUM_PROP_RIGHT: + case NUM_PROP_BOTTOM: + case NUM_PROP_LEFT: + cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); + break; + + case NUM_PROP_PADDING_TOP: + case NUM_PROP_PADDING_RIGHT: + case NUM_PROP_PADDING_BOTTOM: + case NUM_PROP_PADDING_LEFT: + case NUM_PROP_BORDER_TOP: + case NUM_PROP_BORDER_RIGHT: + case NUM_PROP_BORDER_BOTTOM: + case NUM_PROP_BORDER_LEFT: + case NUM_PROP_MARGIN_TOP: + case NUM_PROP_MARGIN_RIGHT: + case NUM_PROP_MARGIN_BOTTOM: + case NUM_PROP_MARGIN_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_LENGTH_PX); + break; + + default: + cr_utils_trace_info ("Unknown property"); + break; + } + } + + for (i = 0; i < NB_RGB_PROPS; i++) { + + switch (i) { + /*default foreground color is black */ + case RGB_PROP_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); + break; + + /*default background color is white */ + case RGB_PROP_BACKGROUND_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, + 255, 255, 255, FALSE); + cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, + TRUE) ; + break; + default: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); + break; + } + } + + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + a_this->border_style_props[i] = BORDER_STYLE_NONE; + } + + a_this->display = DISPLAY_BLOCK; + a_this->position = POSITION_STATIC; + a_this->float_type = FLOAT_NONE; + a_this->font_style = FONT_STYLE_NORMAL; + a_this->font_variant = FONT_VARIANT_NORMAL; + a_this->font_weight = FONT_WEIGHT_NORMAL; + a_this->font_stretch = FONT_STRETCH_NORMAL; + a_this->white_space = WHITE_SPACE_NORMAL; + cr_font_size_set_predefined_absolute_font_size + (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ; + a_this->inherited_props_resolved = FALSE ; + + return CR_OK; +} + +/** + *Resolves the inherited properties. + *The function sets the "inherited" properties to either the value of + *their parent properties. + *This function is *NOT* recursive. So the inherited properties of + *the parent style must have been resolved prior to calling this function. + *@param a_this the instance where + *@return CR_OK if a root node is found and the propagation is successful, + *an error code otherwise + */ +enum CRStatus +cr_style_resolve_inherited_properties (CRStyle *a_this) +{ + enum CRStatus ret = CR_OK; + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ; + + if (a_this->inherited_props_resolved == TRUE) + return CR_OK ; + + for (i=0 ; i < NB_NUM_PROPS ;i++) { + if (a_this->num_props[i].sv.type == NUM_INHERIT) { + cr_num_copy (&a_this->num_props[i].cv, + &a_this->parent_style->num_props[i].cv); + } + } + for (i=0; i < NB_RGB_PROPS; i++) { + if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) { + cr_rgb_copy ( + &a_this->rgb_props[i].cv, + &a_this->parent_style->rgb_props[i].cv); + } + } + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) { + a_this->border_style_props[i] = + a_this->parent_style->border_style_props[i]; + } + } + + if (a_this->display == DISPLAY_INHERIT) { + a_this->display = a_this->parent_style->display; + } + if (a_this->position == POSITION_INHERIT) { + a_this->position = a_this->parent_style->position; + } + if (a_this->float_type == FLOAT_INHERIT) { + a_this->float_type = a_this->parent_style->float_type; + } + if (a_this->font_style == FONT_STYLE_INHERIT) { + a_this->font_style = a_this->parent_style->font_style; + } + if (a_this->font_variant == FONT_VARIANT_INHERIT) { + a_this->font_variant = a_this->parent_style->font_variant; + } + if (a_this->font_weight == FONT_WEIGHT_INHERIT) { + a_this->font_weight = a_this->parent_style->font_weight; + } + if (a_this->font_stretch == FONT_STRETCH_INHERIT) { + a_this->font_stretch = a_this->parent_style->font_stretch; + } + /*NULL is inherit marker for font_famiy*/ + if (a_this->font_family == NULL) { + a_this->font_family = a_this->parent_style->font_family; + } + if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) { + cr_font_size_copy (&a_this->font_size.cv, + &a_this->parent_style->font_size.cv) ; + } + a_this->inherited_props_resolved = TRUE ; + return ret; +} + +/** + *Walks through a css2 property declaration, and populated the + *according field(s) in the #CRStyle structure. + *If the properties or their value(s) are/is not known, + *sets the corresponding field(s) of #CRStyle to its/their default + *value(s) + *@param a_this the instance of #CRStyle to set. + *@param a_decl the declaration from which the #CRStyle fields are set. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl) +{ + CRTerm *value = NULL; + enum CRStatus status = CR_OK; + + enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN; + + g_return_val_if_fail (a_this && a_decl + && a_decl + && a_decl->property + && a_decl->property->stryng + && a_decl->property->stryng->str, + CR_BAD_PARAM_ERROR); + + prop_id = cr_style_get_prop_id + ((const guchar *) a_decl->property->stryng->str); + + value = a_decl->value; + switch (prop_id) { + case PROP_ID_PADDING_TOP: + status = set_prop_padding_x_from_value + (a_this, value, DIR_TOP); + break; + + case PROP_ID_PADDING_RIGHT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_RIGHT); + break; + case PROP_ID_PADDING_BOTTOM: + status = set_prop_padding_x_from_value + (a_this, value, DIR_BOTTOM); + break; + + case PROP_ID_PADDING_LEFT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_LEFT); + break; + + case PROP_ID_PADDING: + status = set_prop_padding_from_value (a_this, value) ; + break; + + case PROP_ID_BORDER_TOP_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_BORDER_WIDTH: + status = set_prop_border_width_from_value (a_this, value) ; + break ; + + case PROP_ID_BORDER_TOP_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_BORDER_STYLE: + status = set_prop_border_style_from_value (a_this, value) ; + break ; + + case PROP_ID_BORDER_TOP_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_TOP: + status = set_prop_border_x_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT: + status = set_prop_border_x_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM: + status = set_prop_border_x_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT: + status = set_prop_border_x_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_MARGIN_TOP: + status = set_prop_margin_x_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER: + status = set_prop_border_from_value (a_this, value); + break; + + case PROP_ID_MARGIN_RIGHT: + status = set_prop_margin_x_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_MARGIN_BOTTOM: + status = set_prop_margin_x_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_MARGIN_LEFT: + status = set_prop_margin_x_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_MARGIN: + status = set_prop_margin_from_value (a_this, value); + break; + + case PROP_ID_DISPLAY: + status = set_prop_display_from_value (a_this, value); + break; + + case PROP_ID_POSITION: + status = set_prop_position_from_value (a_this, value); + break; + + case PROP_ID_TOP: + status = set_prop_x_from_value (a_this, value, DIR_TOP); + break; + + case PROP_ID_RIGHT: + status = set_prop_x_from_value (a_this, value, DIR_RIGHT); + break; + + case PROP_ID_BOTTOM: + status = set_prop_x_from_value (a_this, value, DIR_BOTTOM); + break; + + case PROP_ID_LEFT: + status = set_prop_x_from_value (a_this, value, DIR_LEFT); + break; + + case PROP_ID_FLOAT: + status = set_prop_float (a_this, value); + break; + + case PROP_ID_WIDTH: + status = set_prop_width (a_this, value); + break; + + case PROP_ID_COLOR: + status = set_prop_color (a_this, value); + break; + + case PROP_ID_BACKGROUND_COLOR: + status = set_prop_background_color (a_this, value); + break; + + case PROP_ID_FONT_FAMILY: + status = set_prop_font_family_from_value (a_this, value); + break; + + case PROP_ID_FONT_SIZE: + status = set_prop_font_size_from_value (a_this, value); + break; + + case PROP_ID_FONT_STYLE: + status = set_prop_font_style_from_value (a_this, value); + break; + + case PROP_ID_FONT_WEIGHT: + status = set_prop_font_weight_from_value (a_this, value); + break; + + case PROP_ID_WHITE_SPACE: + status = set_prop_white_space_from_value(a_this, value); + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + + } + + return status; +} + +/** + *Increases the reference count + *of the current instance of #CRStyle. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_style_ref (CRStyle * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->ref_count++; + return CR_OK; +} + +/** + *Decreases the reference count of + *the current instance of #CRStyle. + *If the reference count reaches 0, the + *instance of #CRStyle is destoyed. + *@param a_this the current instance of #CRStyle. + *@return TRUE if the instance has been destroyed, FALSE + *otherwise. + */ +gboolean +cr_style_unref (CRStyle * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) + a_this->ref_count--; + + if (!a_this->ref_count) { + cr_style_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *Duplicates the current instance of #CRStyle . + *The newly created instance of #CRStyle must be + *freed using cr_style_destroy (). + *@param a_this the current instance of #CRStyle. + *@return the newly duplicated instance of #CRStyle. + */ +CRStyle * +cr_style_dup (CRStyle * a_this) +{ + CRStyle *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + result = cr_style_new (FALSE); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + cr_style_copy (result, a_this); + return result; +} + +/** + *Copies a style data structure into another. + *TODO: this is actually broken because it's based + *on memcpy although some data structures of CRStyle should + *be properly duplicated. + *@param a_dest the destination style datastructure + *@param a_src the source style datastructure. + *@return CR_OK upon successful completion, an error code otherwise + */ +enum CRStatus +cr_style_copy (CRStyle * a_dest, CRStyle * a_src) +{ + g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR); + + memcpy (a_dest, a_src, sizeof (CRStyle)); + return CR_OK; +} + +/** + *dump a CRNumpPropVal in a string. + *@param a_prop_val the numerical property value to dump + *@param a_str the string to dump the numerical property into. + *Note that the string value is appended to a_str. + *@param a_nb_indent the number white chars of indentation. + */ +enum CRStatus +cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val, + GString * a_str, guint a_nb_indent) +{ + enum CRStatus status = CR_OK; + guchar *tmp_str = NULL; + GString *str = NULL; + + g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); + + str = g_string_new (NULL); + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "NumPropVal {"); + tmp_str = cr_num_to_string (&a_prop_val->sv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "sv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + tmp_str = cr_num_to_string (&a_prop_val->cv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "cv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + tmp_str = cr_num_to_string (&a_prop_val->av); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "av: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + g_string_append (str, "}"); + g_string_append (a_str, str->str); + status = CR_OK; + cleanup: + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + if (str) { + g_string_free (str, TRUE); + } + return status; +} + +enum CRStatus +cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val, + GString * a_str, guint a_nb_indent) +{ + enum CRStatus status = CR_OK; + guchar *tmp_str = NULL; + GString *str = NULL; + + g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); + + str = g_string_new (NULL); + + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "RGBPropVal {"); + tmp_str = cr_rgb_to_string (&a_prop_val->sv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "sv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + tmp_str = cr_rgb_to_string (&a_prop_val->cv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "cv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + tmp_str = cr_rgb_to_string (&a_prop_val->av); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "av: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + g_string_append (str, "}"); + g_string_append (a_str, str->str); + status = CR_OK; + cleanup: + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + if (str) { + g_string_free (str, TRUE); + } + return status; +} + +enum CRStatus +cr_style_border_style_to_string (enum CRBorderStyle a_prop, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_prop) { + case BORDER_STYLE_NONE: + str = (gchar *) "border-style-none"; + break; + case BORDER_STYLE_HIDDEN: + str = (gchar *) "border-style-hidden"; + break; + case BORDER_STYLE_DOTTED: + str = (gchar *) "border-style-dotted"; + break; + case BORDER_STYLE_DASHED: + str = (gchar *) "border-style-dashed"; + break; + case BORDER_STYLE_SOLID: + str = (gchar *) "border-style-solid"; + break; + case BORDER_STYLE_DOUBLE: + str = (gchar *) "border-style-double"; + break; + case BORDER_STYLE_GROOVE: + str = (gchar *) "border-style-groove"; + break; + case BORDER_STYLE_RIDGE: + str = (gchar *) "border-style-ridge"; + break; + case BORDER_STYLE_INSET: + str = (gchar *) "border-style-inset"; + break; + case BORDER_STYLE_OUTSET: + str = (gchar *) "border-style-outset"; + break; + default: + str = (gchar *) "unknown border style"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_display_type_to_string (enum CRDisplayType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case DISPLAY_NONE: + str = (gchar *) "display-none"; + break; + case DISPLAY_INLINE: + str = (gchar *) "display-inline"; + break; + case DISPLAY_BLOCK: + str = (gchar *) "display-block"; + break; + case DISPLAY_LIST_ITEM: + str = (gchar *) "display-list-item"; + break; + case DISPLAY_RUN_IN: + str = (gchar *) "display-run-in"; + break; + case DISPLAY_COMPACT: + str = (gchar *) "display-compact"; + break; + case DISPLAY_MARKER: + str = (gchar *) "display-marker"; + break; + case DISPLAY_TABLE: + str = (gchar *) "display-table"; + break; + case DISPLAY_INLINE_TABLE: + str = (gchar *) "display-inline-table"; + break; + case DISPLAY_TABLE_ROW_GROUP: + str = (gchar *) "display-table-row-group"; + break; + case DISPLAY_TABLE_HEADER_GROUP: + str = (gchar *) "display-table-header-group"; + break; + case DISPLAY_TABLE_FOOTER_GROUP: + str = (gchar *) "display-table-footer-group"; + break; + case DISPLAY_TABLE_ROW: + str = (gchar *) "display-table-row"; + break; + case DISPLAY_TABLE_COLUMN_GROUP: + str = (gchar *) "display-table-column-group"; + break; + case DISPLAY_TABLE_COLUMN: + str = (gchar *) "display-table-column"; + break; + case DISPLAY_TABLE_CELL: + str = (gchar *) "display-table-cell"; + break; + case DISPLAY_TABLE_CAPTION: + str = (gchar *) "display-table-caption"; + break; + case DISPLAY_INHERIT: + str = (gchar *) "display-inherit"; + break; + default: + str = (gchar *) "unknown display property"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; + +} + +enum CRStatus +cr_style_position_type_to_string (enum CRPositionType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case POSITION_STATIC: + str = (gchar *) "position-static"; + break; + case POSITION_RELATIVE: + str = (gchar *) "position-relative"; + break; + case POSITION_ABSOLUTE: + str = (gchar *) "position-absolute"; + break; + case POSITION_FIXED: + str = (gchar *) "position-fixed"; + break; + case POSITION_INHERIT: + str = (gchar *) "position-inherit"; + break; + default: + str = (gchar *) "unknown static property"; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_float_type_to_string (enum CRFloatType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case FLOAT_NONE: + str = (gchar *) "float-none"; + break; + case FLOAT_LEFT: + str = (gchar *) "float-left"; + break; + case FLOAT_RIGHT: + str = (gchar *) "float-right"; + break; + case FLOAT_INHERIT: + str = (gchar *) "float-inherit"; + break; + default: + str = (gchar *) "unknown float property value"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case WHITE_SPACE_NORMAL: + str = (gchar *) "normal"; + break; + case WHITE_SPACE_PRE: + str = (gchar *) "pre"; + break; + case WHITE_SPACE_NOWRAP: + str = (gchar *) "nowrap"; + break; + case WHITE_SPACE_INHERIT: + str = (gchar *) "inherited"; + break; + default: + str = (gchar *) "unknown white space property value"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +/** + *Serializes in instance of #CRStyle into + *a string + *@param a_this the instance of #CRStyle to serialize + *@param a_str the string to serialise the style into. + *if *a_str is NULL, a new GString is instantiated, otherwise + *the style serialisation is appended to the existed *a_str + *@param the number of white space char to use for indentation. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) +{ + const gint INTERNAL_INDENT = 2; + gint indent = a_nb_indent + INTERNAL_INDENT; + gchar *tmp_str = NULL; + GString *str = NULL; + gint i = 0; + + g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR); + + if (!*a_str) { + str = g_string_new (NULL); + } else { + str = *a_str; + } + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "style {\n"); + + /*loop over the num_props and to_string() them */ + for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) { + /* + *to_string() the name of the num_prop + *(using num_prop_code_to_string) + *before outputting it value + */ + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) num_prop_code_to_string ((enum CRNumProp) i); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL"); + } + tmp_str = NULL; + cr_style_num_prop_val_to_string (&a_this->num_props[i], str, + a_nb_indent + + INTERNAL_INDENT); + g_string_append (str, "\n"); + } + /*loop over the rgb_props and to_string() them all */ + for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) { + tmp_str = (gchar *) rgb_prop_code_to_string ((enum CRRgbProp) i); + cr_utils_dump_n_chars2 (' ', str, indent); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL: "); + } + tmp_str = NULL; + cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str, + a_nb_indent + + INTERNAL_INDENT); + g_string_append (str, "\n"); + } + /*loop over the border_style_props and to_string() them */ + for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) { + tmp_str = (gchar *) border_style_prop_code_to_string ((enum CRBorderStyleProp) i); + cr_utils_dump_n_chars2 (' ', str, indent); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL: "); + } + tmp_str = NULL; + cr_style_border_style_to_string (a_this-> + border_style_props[i], str, + 0); + g_string_append (str, "\n"); + } + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "display: "); + cr_style_display_type_to_string (a_this->display, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "position: "); + cr_style_position_type_to_string (a_this->position, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "float-type: "); + cr_style_float_type_to_string (a_this->float_type, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "white-space: "); + cr_style_white_space_type_to_string (a_this->white_space, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "font-family: "); + tmp_str = (gchar *) cr_font_family_to_string (a_this->font_family, TRUE); + if (tmp_str) { + g_string_append (str, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } else { + g_string_append (str, "NULL"); + } + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = cr_font_size_to_string (&a_this->font_size.sv); + if (tmp_str) { + g_string_append_printf (str, "font-size {sv:%s, ", + tmp_str) ; + } else { + g_string_append (str, "font-size {sv:NULL, "); + } + tmp_str = cr_font_size_to_string (&a_this->font_size.cv); + if (tmp_str) { + g_string_append_printf (str, "cv:%s, ", tmp_str); + } else { + g_string_append (str, "cv:NULL, "); + } + tmp_str = cr_font_size_to_string (&a_this->font_size.av); + if (tmp_str) { + g_string_append_printf (str, "av:%s}", tmp_str); + } else { + g_string_append (str, "av:NULL}"); + } + + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust); + if (tmp_str) { + g_string_append_printf (str, "font-size-adjust: %s", tmp_str); + } else { + g_string_append (str, "font-size-adjust: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style); + if (tmp_str) { + g_string_append_printf (str, "font-style: %s", tmp_str); + } else { + g_string_append (str, "font-style: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant); + if (tmp_str) { + g_string_append_printf (str, "font-variant: %s", tmp_str); + } else { + g_string_append (str, "font-variant: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight); + if (tmp_str) { + g_string_append_printf (str, "font-weight: %s", tmp_str); + } else { + g_string_append (str, "font-weight: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch); + if (tmp_str) { + g_string_append_printf (str, "font-stretch: %s", tmp_str); + } else { + g_string_append (str, "font-stretch: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "}"); + + return CR_OK; +} + +/** + *Destructor of the #CRStyle class. + *@param a_this the instance to destroy. + */ +void +cr_style_destroy (CRStyle * a_this) +{ + g_return_if_fail (a_this); + + g_free (a_this); +} + diff --git a/src/3rdparty/libcroco/src/cr-style.h b/src/3rdparty/libcroco/src/cr-style.h new file mode 100644 index 0000000..18aeaad --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-style.h @@ -0,0 +1,339 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_STYLE_H__ +#define __CR_STYLE_H__ + +#include "cr-utils.h" +#include "cr-statement.h" +#include "cr-fonts.h" + +/** + *@file + *The declaration of the #CRStyle class. + */ +G_BEGIN_DECLS + +typedef struct _CRStyle CRStyle ; + +enum CRBorderStyle +{ + BORDER_STYLE_NONE = 0, + BORDER_STYLE_HIDDEN, + BORDER_STYLE_DOTTED, + BORDER_STYLE_DASHED, + BORDER_STYLE_SOLID, + BORDER_STYLE_DOUBLE, + BORDER_STYLE_GROOVE, + BORDER_STYLE_RIDGE, + BORDER_STYLE_INSET, + BORDER_STYLE_OUTSET, + BORDER_STYLE_INHERIT +} ; + +enum CRDisplayType +{ + DISPLAY_NONE, + DISPLAY_INLINE, + DISPLAY_BLOCK, + DISPLAY_LIST_ITEM, + DISPLAY_RUN_IN, + DISPLAY_COMPACT, + DISPLAY_MARKER, + DISPLAY_TABLE, + DISPLAY_INLINE_TABLE, + DISPLAY_TABLE_ROW_GROUP, + DISPLAY_TABLE_HEADER_GROUP, + DISPLAY_TABLE_FOOTER_GROUP, + DISPLAY_TABLE_ROW, + DISPLAY_TABLE_COLUMN_GROUP, + DISPLAY_TABLE_COLUMN, + DISPLAY_TABLE_CELL, + DISPLAY_TABLE_CAPTION, + DISPLAY_INHERIT +} ; + +enum CRPositionType +{ + POSITION_STATIC, + POSITION_RELATIVE, + POSITION_ABSOLUTE, + POSITION_FIXED, + POSITION_INHERIT +} ; + +enum CRFloatType +{ + FLOAT_NONE, + FLOAT_LEFT, + FLOAT_RIGHT, + FLOAT_INHERIT +} ; + +enum CRWhiteSpaceType +{ + WHITE_SPACE_NORMAL, + WHITE_SPACE_PRE, + WHITE_SPACE_NOWRAP, + WHITE_SPACE_INHERIT +} ; + + +#define BORDER_THIN 2 +#define BORDER_MEDIUM 4 +#define BORDER_THICK 6 + + +/** + *A numerical css property value. + *This data type is actually split in 3 parts: + *1/the specified value + *2/the computed value + *3/the actual value. + *To understand the semantic of these three parts, + *see css2 spec chap 6.1 ("Specified, computed and actual values."). + */ +typedef struct _CRNumPropVal CRNumPropVal ; +struct _CRNumPropVal +{ + /**specified value*/ + CRNum sv ; + /**computed value*/ + CRNum cv ; + /**actual value*/ + CRNum av ; +} ; + +/** + *An rgb css property value. + *This data type is actually split in 3 parts: + *1/the specified value + *2/the computed value + *3/the actual value. + *To understand the semantic of these three parts, + *see css2 spec chap 6.1 ("Specified, computed and actual values."). + */ +typedef struct _CRRgbPropVal CRRgbPropVal ; +struct _CRRgbPropVal +{ + /**specified value*/ + CRRgb sv ; + /**computed value*/ + CRRgb cv ; + /**actual value*/ + CRRgb av ; +} ; + + +enum CRNumProp +{ + NUM_PROP_TOP=0, + NUM_PROP_RIGHT, + NUM_PROP_BOTTOM, + NUM_PROP_LEFT,/*3*/ + + NUM_PROP_PADDING_TOP, + NUM_PROP_PADDING_RIGHT, + NUM_PROP_PADDING_BOTTOM, + NUM_PROP_PADDING_LEFT,/*7*/ + + NUM_PROP_BORDER_TOP, + NUM_PROP_BORDER_RIGHT, + NUM_PROP_BORDER_BOTTOM, + NUM_PROP_BORDER_LEFT,/*11*/ + + NUM_PROP_MARGIN_TOP, + NUM_PROP_MARGIN_RIGHT, + NUM_PROP_MARGIN_BOTTOM, + NUM_PROP_MARGIN_LEFT,/*15*/ + + NUM_PROP_WIDTH, + + /*must be last*/ + NB_NUM_PROPS +} ; + +enum CRRgbProp +{ + RGB_PROP_BORDER_TOP_COLOR = 0, + RGB_PROP_BORDER_RIGHT_COLOR, + RGB_PROP_BORDER_BOTTOM_COLOR, + RGB_PROP_BORDER_LEFT_COLOR, + RGB_PROP_COLOR, + RGB_PROP_BACKGROUND_COLOR, + + /*must be last*/ + NB_RGB_PROPS +} ; + + +enum CRBorderStyleProp +{ + BORDER_STYLE_PROP_TOP = 0, + BORDER_STYLE_PROP_RIGHT, + BORDER_STYLE_PROP_BOTTOM, + BORDER_STYLE_PROP_LEFT, + + /*must be last*/ + NB_BORDER_STYLE_PROPS +} ; + +enum CRBoxOffsetProp +{ + BOX_OFFSET_PROP_TOP = 0, + BOX_OFFSET_PROP_RIGHT, + BOX_OFFSET_PROP_BOTTOM, + BOX_OFFSET_PROP_LEFT, + + /*must be last*/ + NB_BOX_OFFSET_PROPS +} ; + +typedef struct _CRFontSizeVal CRFontSizeVal ; +struct _CRFontSizeVal { + /*specified value*/ + CRFontSize sv ; + /*computed value*/ + CRFontSize cv ; + /*actual value*/ + CRFontSize av ; +} ; + +/** + *The css2 style class. + *Contains computed and actual values + *inferred from the declarations found + *in the stylesheets. + *See css2 spec chapter 6. + */ +struct _CRStyle +{ + /** + *numerical properties. + *the properties are indexed by + *enum #CRNumProp. + */ + CRNumPropVal num_props[NB_NUM_PROPS] ; + + /** + *color properties. + *They are indexed by enum #CRRgbProp . + */ + CRRgbPropVal rgb_props[NB_RGB_PROPS] ; + + /** + *border style properties. + *They are indexed by enum #CRBorderStyleProp . + */ + enum CRBorderStyle border_style_props[NB_BORDER_STYLE_PROPS] ; + + /**box display type*/ + enum CRDisplayType display ; + + /**the positioning scheme*/ + enum CRPositionType position ; + + /**the float property*/ + enum CRFloatType float_type ; + + /* + *the 'font-family' property. + */ + CRFontFamily *font_family ; + + /** + *the 'font-size' property. + */ + CRFontSizeVal font_size ; + CRFontSizeAdjust *font_size_adjust ; + enum CRFontStyle font_style ; + enum CRFontVariant font_variant ; + enum CRFontWeight font_weight ; + enum CRFontStretch font_stretch ; + + /** + * the 'tex' properties + */ + enum CRWhiteSpaceType white_space; + + gboolean inherited_props_resolved ; + CRStyle *parent_style ; + gulong ref_count ; +} ; + +enum CRStatus cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code, + GString * a_str, guint a_nb_indent) ; + +enum CRStatus cr_style_num_prop_val_to_string (CRNumPropVal *a_prop_val, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_rgb_prop_val_to_string (CRRgbPropVal *a_prop_val, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_border_style_to_string (enum CRBorderStyle a_prop, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_display_type_to_string (enum CRDisplayType a_code, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_position_type_to_string (enum CRPositionType a_code, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_float_type_to_string (enum CRFloatType a_code, + GString *a_str, + guint a_nb_indent) ; + +CRStyle * cr_style_new (gboolean a_set_props_to_initial_values) ; + +enum CRStatus cr_style_set_props_to_default_values (CRStyle *a_this) ; +enum CRStatus cr_style_set_props_to_initial_values (CRStyle *a_this) ; +enum CRStatus cr_style_resolve_inherited_properties (CRStyle *a_this) ; +enum CRStatus cr_style_propagate_from_parent (CRStyle *a_this); + +enum CRStatus cr_style_set_style_from_decl (CRStyle *a_this, + CRDeclaration *a_decl) ; + + +enum CRStatus cr_style_copy (CRStyle *a_dest, CRStyle *a_src) ; + +enum CRStatus cr_style_ref (CRStyle *a_this) ; + +gboolean cr_style_unref (CRStyle *a_this) ; + +void cr_style_destroy (CRStyle *a_this) ; + +CRStyle * cr_style_dup (CRStyle *a_this) ; + +enum CRStatus cr_style_to_string (CRStyle *a_this, + GString **a_str, + guint a_nb_indent) ; + +G_END_DECLS + +#endif /*__CR_STYLE_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-stylesheet.c b/src/3rdparty/libcroco/src/cr-stylesheet.c new file mode 100644 index 0000000..2ea0fa6 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-stylesheet.c @@ -0,0 +1,268 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2004 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "string.h" +#include "cr-stylesheet.h" + +/** + *@file + *The definition of the #CRStyleSheet class + */ + +/** + *Constructor of the #CRStyleSheet class. + *@param the initial list of css statements. + *@return the newly built css2 stylesheet, or NULL in case of error. + */ +CRStyleSheet * +cr_stylesheet_new (CRStatement * a_stmts) +{ + CRStyleSheet *result; + + result = (CRStyleSheet *) g_try_malloc (sizeof (CRStyleSheet)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStyleSheet)); + + if (a_stmts) + result->statements = a_stmts; + + result->ref_count = 1; + + return result; +} + +/** + *@param a_this the current instance of #CRStyleSheet + *@return the serialized stylesheet. + */ +gchar * +cr_stylesheet_to_string (CRStyleSheet const *a_this) +{ + gchar *str = NULL; + GString *stringue = NULL; + CRStatement const *cur_stmt = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + + for (cur_stmt = a_this->statements; + cur_stmt; cur_stmt = cur_stmt->next) { + if (cur_stmt->prev) { + g_string_append (stringue, "\n\n") ; + } + str = cr_statement_to_string (cur_stmt, 0) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + } + + if (a_this->next) { + str = cr_stylesheet_to_string (a_this->next); + if (str) { + g_string_append (stringue, "\n") ; + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + } + + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return str ; +} + +/** + *Dumps the current css2 stylesheet to a file. + *@param a_this the current instance of #CRStyleSheet. + *@param a_fp the destination file + */ +void +cr_stylesheet_dump (CRStyleSheet const * a_this, FILE * a_fp) +{ + gchar *str = NULL ; + + g_return_if_fail (a_this); + + str = cr_stylesheet_to_string (a_this) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Return the number of rules in the stylesheet. + *@param a_this the current instance of #CRStyleSheet. + *@return number of rules in the stylesheet. + */ +gint +cr_stylesheet_nr_rules (CRStyleSheet const * a_this) +{ + g_return_val_if_fail (a_this, -1); + + return cr_statement_nr_rules (a_this->statements); +} + +/** + *Use an index to get a CRStatement from the rules in a given stylesheet. + *@param a_this the current instance of #CRStatement. + *@param itemnr the index into the rules. + *@return CRStatement at position itemnr, if itemnr > number of rules - 1, + *it will return NULL. + */ +CRStatement * +cr_stylesheet_statement_get_from_list (CRStyleSheet * a_this, int itemnr) +{ + g_return_val_if_fail (a_this, NULL); + + return cr_statement_get_from_list (a_this->statements, itemnr); +} + +/** + *Appends a new stylesheet to the current list of #CRStylesheet, setting + *the "origin" of the new stylesheet to be the same as the others in list. + * + *@param a_this the "this pointer" of the current instance + *of #CRStylesheet . + *@param a_new_stylesheet the stylesheet to append. + *@return the list of stylesheets with the a_new_stylesheet appended to it. + */ +CRStyleSheet * +cr_stylesheet_append_stylesheet (CRStyleSheet * a_this, CRStyleSheet * a_new_stylesheet) +{ + CRStyleSheet *cur = NULL; + + g_return_val_if_fail (a_new_stylesheet, NULL); + + if (a_this == NULL) + return a_new_stylesheet; + + for (cur = a_this; cur->next; cur = cur->next) ; + + cur->next = a_new_stylesheet; + a_new_stylesheet->prev = cur; + + /* The "origin" must apriori be the same for all stylesheets + in a list. We must set it correctly or errors will occur in + put_css_properties_in_props_list(). The "origin" of the initial + stylesheet in the list is set in cr_cascade_set_sheet(). */ + a_new_stylesheet->origin = cur->origin; + + return a_this; +} + +/** + * cr_stylesheet_unlink: + *@a_this: the stylesheet to unlink. + * + *Unlinks the stylesheet from the stylesheet list. + * + *Returns a pointer to the unlinked stylesheet in + *case of a successfull completion, NULL otherwise. + */ +CRStyleSheet * +cr_stylesheet_unlink (CRStyleSheet * a_this) +{ + CRStyleSheet *result = a_this; + + g_return_val_if_fail (result, NULL); + + /* + *some sanity checks first + */ + if (a_this->prev) { + g_return_val_if_fail (a_this->prev->next == a_this, NULL); + + } + if (a_this->next) { + g_return_val_if_fail (a_this->next->prev == a_this, NULL); + } + + /* + *now, the real unlinking job. + */ + if (a_this->prev) { + a_this->prev->next = a_this->next; + } + if (a_this->next) { + a_this->next->prev = a_this->prev; + } + + a_this->next = NULL; + a_this->prev = NULL; + + return a_this; +} + +void +cr_stylesheet_ref (CRStyleSheet * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +gboolean +cr_stylesheet_unref (CRStyleSheet * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (!--a_this->ref_count) { + cr_stylesheet_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *Destructor of the #CRStyleSheet class. + *@param a_this the current instance of the #CRStyleSheet class. + */ +void +cr_stylesheet_destroy (CRStyleSheet * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->statements) { + cr_statement_destroy (a_this->statements); + a_this->statements = NULL; + } + + if (a_this->next) { + cr_stylesheet_destroy (a_this->next); + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-stylesheet.h b/src/3rdparty/libcroco/src/cr-stylesheet.h new file mode 100644 index 0000000..cf7b093 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-stylesheet.h @@ -0,0 +1,117 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * see COPYRIGHTS file for copyright information. + */ + + +#ifndef __CR_STYLESHEET_H__ +#define __CR_STYLESHEET_H__ + +#include "cr-utils.h" +#include "cr-statement.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRStyleSheet class. + */ + + +enum CRStyleOrigin +{ + /*Please don't change the order of + *the values enumerated here ... + *New values should be added at the end, + *just before ORIGIN_END. + */ + ORIGIN_UA = 0, + ORIGIN_USER, + ORIGIN_AUTHOR, + + /*must always be the last one*/ + NB_ORIGINS +} ; + +/** + *An abstraction of a css stylesheet as defined + *by the css2 spec in chapter 4. + */ +struct _CRStyleSheet +{ + /**The css statements list*/ + CRStatement *statements ; + + enum CRStyleOrigin origin ; + + /*the parent import rule, if any.*/ + CRStatement *parent_import_rule ; + + /**custom data used by libcroco*/ + gpointer croco_data ; + + /** + *custom application data pointer + *Can be used by applications. + */ + gpointer app_data ; + + /** + *the reference count of this insance + *Please, don't never ever modify it + *directly. Use cr_stylesheet_ref() + *and cr_stylesheet_unref() instead. + */ + gulong ref_count ; + + /** + * A link to the next stylesheet. + */ + CRStyleSheet *next; + + /** + * A link to the previous stylesheet. + */ + CRStyleSheet *prev; +} ; + +CRStyleSheet * cr_stylesheet_new (CRStatement *a_stmts) ; + +gchar * cr_stylesheet_to_string (CRStyleSheet const *a_this) ; + +void cr_stylesheet_dump (CRStyleSheet const *a_this, FILE *a_fp) ; + +gint cr_stylesheet_nr_rules (CRStyleSheet const *a_this) ; + +CRStatement * cr_stylesheet_statement_get_from_list (CRStyleSheet *a_this, int itemnr) ; + +CRStyleSheet * cr_stylesheet_append_stylesheet (CRStyleSheet *a_this, CRStyleSheet *a_new_stylesheet) ; + +CRStyleSheet * cr_stylesheet_unlink (CRStyleSheet *a_this) ; + +void cr_stylesheet_ref (CRStyleSheet *a_this) ; + +gboolean cr_stylesheet_unref (CRStyleSheet *a_this) ; + +void cr_stylesheet_destroy (CRStyleSheet *a_this) ; + +G_END_DECLS + +#endif /*__CR_STYLESHEET_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-term.c b/src/3rdparty/libcroco/src/cr-term.c new file mode 100644 index 0000000..e370103 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-term.c @@ -0,0 +1,744 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <stdio.h> +#include <string.h> +#include "cr-term.h" +#include "cr-num.h" +#include "cr-parser.h" + +/** + * Adds a quoted string onto the end of a GString, expanding it if necessary. + * Uses either single or double quotes. + * + * @pre val is not NULL and is null-terminated. Note that this is true for all + * GString::str values. + */ +static void +_string_append_quoted (GString *string, const gchar *val) +{ + gchar quote = '\''; + + if (!val) { + g_assert_not_reached (); + val = ""; + } + + if (strchr (val, '\'') && !strchr (val, '"')) { + quote = '"'; + } + + g_string_append_c (string, quote); + + for (; *val; ++val) { + if (*val == quote || *val == '\\') { + g_string_append_c (string, '\\'); + } + g_string_append_c (string, *val); + } + + g_string_append_c (string, quote); +} + +/** + *@file + *Definition of the #CRTem class. + */ + +static void +cr_term_clear (CRTerm * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case TERM_NUMBER: + if (a_this->content.num) { + cr_num_destroy (a_this->content.num); + a_this->content.num = NULL; + } + break; + + case TERM_FUNCTION: + if (a_this->ext_content.func_param) { + cr_term_destroy (a_this->ext_content.func_param); + a_this->ext_content.func_param = NULL; + } + // fall through + case TERM_STRING: + case TERM_IDENT: + case TERM_URI: + case TERM_HASH: + if (a_this->content.str) { + cr_string_destroy (a_this->content.str); + a_this->content.str = NULL; + } + break; + + case TERM_RGB: + if (a_this->content.rgb) { + cr_rgb_destroy (a_this->content.rgb); + a_this->content.rgb = NULL; + } + break; + + case TERM_UNICODERANGE: + case TERM_NO_TYPE: + default: + break; + } + + a_this->type = TERM_NO_TYPE; + a_this->n = FALSE; +} + +/** + *Instantiate a #CRTerm. + *@return the newly build instance + *of #CRTerm. + */ +CRTerm * +cr_term_new (void) +{ + CRTerm *result = NULL; + + result = (CRTerm *) g_try_malloc (sizeof (CRTerm)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRTerm)); + return result; +} + +/** + *Parses an expression as defined by the css2 spec + *and builds the expression as a list of terms. + *@param a_buf the buffer to parse. + *@return a pointer to the first term of the expression or + *NULL if parsing failed. + */ +CRTerm * +cr_term_parse_expression_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRParser *parser = NULL; + CRTerm *result = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen ((const char *) a_buf), + a_encoding, FALSE); + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) { + goto cleanup; + } + status = cr_parser_parse_expr (parser, &result); + if (status != CR_OK) { + if (result) { + cr_term_destroy (result); + result = NULL; + } + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + return result; +} + +enum CRStatus +cr_term_set_number (CRTerm * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_NUMBER; + a_this->content.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_term_set_function (CRTerm * a_this, CRString * a_func_name, + CRTerm * a_func_param) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_FUNCTION; + a_this->content.str = a_func_name; + a_this->ext_content.func_param = a_func_param; + return CR_OK; +} + +enum CRStatus +cr_term_set_string (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_STRING; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_ident (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_IDENT; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_uri (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_URI; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_rgb (CRTerm * a_this, CRRgb * a_rgb) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_RGB; + a_this->content.rgb = a_rgb; + return CR_OK; +} + +enum CRStatus +cr_term_set_hash (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_HASH; + a_this->content.str = a_str; + return CR_OK; +} + +/** + *Appends a new term to the current list of #CRTerm. + * + *@param a_this the "this pointer" of the current instance + *of #CRTerm . + *@param a_new_term the term to append. + *@return the list of terms with the a_new_term appended to it. + */ +CRTerm * +cr_term_append_term (CRTerm * a_this, CRTerm * a_new_term) +{ + CRTerm *cur = NULL; + + g_return_val_if_fail (a_new_term, NULL); + + if (a_this == NULL) + return a_new_term; + + for (cur = a_this; cur->next; cur = cur->next) ; + + cur->next = a_new_term; + a_new_term->prev = cur; + + return a_this; +} + +/** + *Prepends a term to the list of terms represented by a_this. + * + *@param a_this the "this pointer" of the current instance of + *#CRTerm . + *@param a_new_term the term to prepend. + *@return the head of the new list. + */ +CRTerm * +cr_term_prepend_term (CRTerm * a_this, CRTerm * a_new_term) +{ + g_return_val_if_fail (a_this && a_new_term, NULL); + + a_new_term->next = a_this; + a_this->prev = a_new_term; + + return a_new_term; +} + +/** + *Serializes the expression represented by + *the chained instances of #CRterm. + *@param a_this the current instance of #CRTerm + *@return the zero terminated string containing the serialized + *form of #CRTerm. MUST BE FREED BY THE CALLER using g_free(). + */ +guchar * +cr_term_to_string (CRTerm const * a_this) +{ + GString *str_buf = NULL; + CRTerm const *cur = NULL; + guchar *result = NULL, + *content = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + for (cur = a_this; cur; cur = cur->next) { + if ((cur->content.str == NULL) + && (cur->content.num == NULL) + && (cur->content.str == NULL) + && (cur->content.rgb == NULL)) + continue; + + switch (cur->the_operator) { + case DIVIDE: + g_string_append (str_buf, " / "); + break; + + case COMMA: + g_string_append (str_buf, ", "); + break; + + case NO_OP: + if (cur->prev) { + g_string_append (str_buf, " "); + } + break; + default: + + break; + } + + switch (cur->unary_op) { + case PLUS_UOP: + g_string_append (str_buf, "+"); + break; + + case MINUS_UOP: + g_string_append (str_buf, "-"); + break; + + default: + break; + } + + switch (cur->type) { + case TERM_NUMBER: + if (cur->content.num) { + content = cr_num_to_string (cur->content.num); + } + + if (content) { + g_string_append (str_buf, (const gchar *) content); + g_free (content); + content = NULL; + } + + break; + + case TERM_FUNCTION: + if (cur->content.str) { + g_string_append_printf (str_buf, "%s(", + cur->content.str->stryng->str); + + if (cur->ext_content.func_param) { + guchar *tmp_str = NULL; + + tmp_str = cr_term_to_string + (cur-> + ext_content.func_param); + + if (tmp_str) { + g_string_append (str_buf, + (const gchar *) tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + g_string_append (str_buf, ")"); + } + + break; + + case TERM_STRING: + if (cur->content.str) { + _string_append_quoted (str_buf, + cur->content.str->stryng->str); + } + break; + + case TERM_IDENT: + if (cur->content.str && cur->content.str->stryng->str) { + g_string_append (str_buf, cur->content.str->stryng->str); + } + break; + + case TERM_URI: + if (cur->content.str) { + g_string_append_printf + (str_buf, "url(%s)", cur->content.str->stryng->str); + } + break; + + case TERM_RGB: + if (cur->content.rgb) { + guchar *tmp_str = NULL; + + g_string_append (str_buf, "rgb("); + tmp_str = cr_rgb_to_string (cur->content.rgb); + + if (tmp_str) { + g_string_append (str_buf, (const gchar *) tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append (str_buf, ")"); + } + + break; + + case TERM_UNICODERANGE: + g_string_append + (str_buf, + "?found unicoderange: dump not supported yet?"); + break; + + case TERM_HASH: + if (cur->content.str) { + g_string_append_printf (str_buf, + "#%s", cur->content.str->stryng->str); + } + break; + + default: + g_string_append (str_buf, + "Unrecognized Term type"); + break; + } + } + + if (str_buf) { + result =(guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +guchar * +cr_term_one_to_string (CRTerm const * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL, + *content = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if ((a_this->content.str == NULL) + && (a_this->content.num == NULL) + && (a_this->content.str == NULL) + && (a_this->content.rgb == NULL)) + return NULL ; + + switch (a_this->the_operator) { + case DIVIDE: + g_string_append_printf (str_buf, " / "); + break; + + case COMMA: + g_string_append_printf (str_buf, ", "); + break; + + case NO_OP: + if (a_this->prev) { + g_string_append_printf (str_buf, " "); + } + break; + default: + + break; + } + + switch (a_this->unary_op) { + case PLUS_UOP: + g_string_append_printf (str_buf, "+"); + break; + + case MINUS_UOP: + g_string_append_printf (str_buf, "-"); + break; + + default: + break; + } + + switch (a_this->type) { + case TERM_NUMBER: + if (a_this->content.num) { + content = cr_num_to_string (a_this->content.num); + } + + if (content) { + g_string_append (str_buf, (const gchar *) content); + g_free (content); + content = NULL; + } + + break; + + case TERM_FUNCTION: + if (a_this->content.str) { + g_string_append_printf (str_buf, "%s(", + a_this->content.str->stryng->str); + + if (a_this->ext_content.func_param) { + guchar *tmp_str = NULL; + + tmp_str = cr_term_to_string + (a_this-> + ext_content.func_param); + + if (tmp_str) { + g_string_append_printf + (str_buf, + "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + + g_string_append_printf (str_buf, ")"); + } + } + + break; + + case TERM_STRING: + if (a_this->content.str) { + _string_append_quoted (str_buf, + a_this->content.str->stryng->str); + } + break; + + case TERM_IDENT: + if (a_this->content.str && a_this->content.str->stryng->str) { + g_string_append (str_buf, a_this->content.str->stryng->str); + } + break; + + case TERM_URI: + if (a_this->content.str) { + g_string_append_printf + (str_buf, "url(%s)", a_this->content.str->stryng->str); + } + break; + + case TERM_RGB: + if (a_this->content.rgb) { + guchar *tmp_str = NULL; + + g_string_append_printf (str_buf, "rgb("); + tmp_str = cr_rgb_to_string (a_this->content.rgb); + + if (tmp_str) { + g_string_append (str_buf, (const gchar *) tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append_printf (str_buf, ")"); + } + + break; + + case TERM_UNICODERANGE: + g_string_append_printf + (str_buf, + "?found unicoderange: dump not supported yet?"); + break; + + case TERM_HASH: + if (a_this->content.str) { + g_string_append_printf (str_buf, + "#%s", a_this->content.str->stryng->str); + } + break; + + default: + g_string_append_printf (str_buf, + "%s", + "Unrecognized Term type"); + break; + } + + if (str_buf) { + result = (guchar *) str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + *Dumps the expression (a list of terms connected by operators) + *to a file. + *TODO: finish the dump. The dump of some type of terms have not yet been + *implemented. + *@param a_this the current instance of #CRTerm. + *@param a_fp the destination file pointer. + */ +void +cr_term_dump (CRTerm const * a_this, FILE * a_fp) +{ + guchar *content = NULL; + + g_return_if_fail (a_this); + + content = cr_term_to_string (a_this); + + if (content) { + fprintf (a_fp, "%s", content); + g_free (content); + } +} + +/** + *Return the number of terms in the expression. + *@param a_this the current instance of #CRTerm. + *@return number of terms in the expression. + */ +int +cr_term_nr_values (CRTerm const *a_this) +{ + CRTerm const *cur = NULL ; + int nr = 0; + + g_return_val_if_fail (a_this, -1) ; + + for (cur = a_this ; cur ; cur = cur->next) + nr ++; + return nr; +} + +/** + *Use an index to get a CRTerm from the expression. + *@param a_this the current instance of #CRTerm. + *@param itemnr the index into the expression. + *@return CRTerm at position itemnr, if itemnr > number of terms - 1, + *it will return NULL. + */ +CRTerm * +cr_term_get_from_list (CRTerm *a_this, int itemnr) +{ + CRTerm *cur = NULL ; + int nr = 0; + + g_return_val_if_fail (a_this, NULL) ; + + for (cur = a_this ; cur ; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + *Increments the reference counter of the current instance + *of #CRTerm.* + *@param a_this the current instance of #CRTerm. + */ +void +cr_term_ref (CRTerm * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + *Decrements the ref count of the current instance of + *#CRTerm. If the ref count reaches zero, the instance is + *destroyed. + *@param a_this the current instance of #CRTerm. + *@return TRUE if the current instance has been destroyed, FALSE otherwise. + */ +gboolean +cr_term_unref (CRTerm * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_term_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *The destructor of the #CRTerm class. + *@param a_this the "this pointer" of the current instance + *of #CRTerm. + */ +void +cr_term_destroy (CRTerm * const a_this) +{ + g_return_if_fail (a_this); + + cr_term_clear (a_this); + + if (a_this->next) { + cr_term_destroy (a_this->next); + a_this->next = NULL; + } + + g_free (a_this); +} + +// vi:sw=8:ts=8 diff --git a/src/3rdparty/libcroco/src/cr-term.h b/src/3rdparty/libcroco/src/cr-term.h new file mode 100644 index 0000000..39b9c6a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-term.h @@ -0,0 +1,195 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <stdio.h> +#include <glib.h> +#include "cr-utils.h" +#include "cr-rgb.h" +#include "cr-num.h" +#include "cr-string.h" + +#ifndef __CR_TERM_H__ +#define __CR_TERM_H__ + +G_BEGIN_DECLS + +/** + *@file + *Declaration of the #CRTerm class. + */ + +enum CRTermType +{ + TERM_NO_TYPE = 0, + TERM_NUMBER, + TERM_FUNCTION, + TERM_STRING, + TERM_IDENT, + TERM_URI, + TERM_RGB, + TERM_UNICODERANGE, + TERM_HASH +} ; + + +enum UnaryOperator +{ + NO_UNARY_UOP = 0, + PLUS_UOP, + MINUS_UOP, + EMPTY_UNARY_UOP +} ; + +enum Operator +{ + NO_OP = 0, + DIVIDE, + COMMA +} ; + +struct _CRTerm ; +typedef struct _CRTerm CRTerm ; + +/** + *An abstraction of a css2 term as + *defined in the CSS2 spec in appendix D.1: + *term ::= + *[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* + *| ANGLE S* | TIME S* | FREQ S* | function ] + * | STRING S* | IDENT S* | URI S* | RGB S* + *| UNICODERANGE S* | hexcolor + */ +struct _CRTerm +{ + /** + *The type of the term. + */ + enum CRTermType type ; + + /** + *The unary operator associated to + *the current term. + */ + enum UnaryOperator unary_op ; + + /** + *The operator associated to the current term. + */ + enum Operator the_operator ; + + + /** + *The content of the term. + *Depending of the type of the term, + *this holds either a number, a percentage ... + */ + union + { + CRNum *num ; + CRString * str ; + CRRgb * rgb ; + } content ; + + /** + *If the term is of type UNICODERANGE, + *this field holds the upper bound of the range. + *if the term is of type FUNCTION, this holds + *an instance of CRTerm that represents + * the expression which is the argument of the function. + */ + union + { + CRTerm *func_param ; + } ext_content ; + + /** + *A flag to indicate if there is an n as in the nth child expression 'an+b'. + */ + gboolean n; + + /** + *A spare pointer, just in case. + *Can be used by the application. + */ + gpointer app_data ; + + glong ref_count ; + + /** + *A pointer to the next term, + *just in case this term is part of + *an expression. + */ + CRTerm *next ; + + /** + *A pointer to the previous + *term. + */ + CRTerm *prev ; + CRParsingLocation location ; +} ; + +CRTerm * cr_term_parse_expression_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRTerm * cr_term_new (void) ; + +enum CRStatus cr_term_set_number (CRTerm *a_this, CRNum *a_num) ; + +enum CRStatus cr_term_set_function (CRTerm *a_this, + CRString *a_func_name, + CRTerm *a_func_param) ; + +enum CRStatus cr_term_set_string (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_ident (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_uri (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_rgb (CRTerm *a_this, CRRgb *a_rgb) ; + +enum CRStatus cr_term_set_hash (CRTerm *a_this, CRString *a_str) ; + +CRTerm * cr_term_append_term (CRTerm *a_this, CRTerm *a_new_term) ; + +CRTerm * cr_term_prepend_term (CRTerm *a_this, CRTerm *a_new_term) ; + +guchar * cr_term_to_string (CRTerm const *a_this) ; + +guchar * cr_term_one_to_string (CRTerm const * a_this) ; + +void cr_term_dump (CRTerm const *a_this, FILE *a_fp) ; + +int cr_term_nr_values (CRTerm const *a_this) ; + +CRTerm * cr_term_get_from_list (CRTerm *a_this, int itemnr) ; + +void cr_term_ref (CRTerm *a_this) ; + +gboolean cr_term_unref (CRTerm *a_this) ; + +void cr_term_destroy (CRTerm * a_term) ; + +G_END_DECLS + +#endif /*__CR_TERM_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-tknzr.c b/src/3rdparty/libcroco/src/cr-tknzr.c new file mode 100644 index 0000000..821f89a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-tknzr.c @@ -0,0 +1,2777 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyrights information. + */ + +/** + *@file + *The definition of the #CRTknzr (tokenizer) + *class. + */ + +#include "string.h" +#include "math.h" +#include "cr-tknzr.h" +#include "cr-doc-handler.h" + +struct _CRTknzrPriv { + /**The parser input stream of bytes*/ + CRInput *input; + + /** + *A cache where tknzr_unget_token() + *puts back the token. tknzr_get_next_token() + *first look in this cache, and if and + *only if it's empty, fetches the next token + *from the input stream. + */ + CRToken *token_cache; + + /** + *The position of the end of the previous token + *or char fetched. + */ + CRInputPos prev_pos; + + CRDocHandler *sac_handler; + + /** + *The reference count of the current instance + *of #CRTknzr. Is manipulated by cr_tknzr_ref() + *and cr_tknzr_unref(). + */ + glong ref_count; +}; + +#define PRIVATE(obj) ((obj)->priv) + +/** + *return TRUE if the character is a number ([0-9]), FALSE otherwise + *@param a_char the char to test. + */ +#define IS_NUM(a_char) (((a_char) >= '0' && (a_char) <= '9')?TRUE:FALSE) + +/** + *Checks if 'status' equals CR_OK. If not, goto the 'error' label. + * + *@param status the status (of type enum CRStatus) to test. + *@param is_exception if set to FALSE, the final status returned the + *current function will be CR_PARSING_ERROR. If set to TRUE, the + *current status will be the current value of the 'status' variable. + * + */ +#define CHECK_PARSING_STATUS(status, is_exception) \ +if ((status) != CR_OK) \ +{ \ + if (is_exception == FALSE) \ + { \ + status = CR_PARSING_ERROR ; \ + } \ + goto error ; \ +} + +/** + *Peeks the next char from the input stream of the current tokenizer. + *invokes CHECK_PARSING_STATUS on the status returned by + *cr_tknzr_input_peek_char(). + * + *@param the current instance of #CRTkzr. + *@param to_char a pointer to the char where to store the + *char peeked. + */ +#define PEEK_NEXT_CHAR(a_tknzr, a_to_char) \ +{\ +status = cr_tknzr_peek_char (a_tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) \ +} + +/** + *Reads the next char from the input stream of the current parser. + *In case of error, jumps to the "error:" label located in the + *function where this macro is called. + *@param parser the current instance of #CRTknzr + *@param to_char a pointer to the guint32 char where to store + *the character read. + */ +#define READ_NEXT_CHAR(a_tknzr, to_char) \ +status = cr_tknzr_read_char (a_tknzr, to_char) ;\ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Gets information about the current position in + *the input of the parser. + *In case of failure, this macro returns from the + *calling function and + *returns a status code of type enum #CRStatus. + *@param parser the current instance of #CRTknzr. + *@param pos out parameter. A pointer to the position + *inside the current parser input. Must + */ +#define RECORD_INITIAL_POS(a_tknzr, a_pos) \ +status = cr_input_get_cur_pos (PRIVATE \ +(a_tknzr)->input, a_pos) ; \ +g_return_val_if_fail (status == CR_OK, status) + +/** + *Gets the address of the current byte inside the + *parser input. + *@param parser the current instance of #CRTknzr. + *@param addr out parameter a pointer (guchar*) + *to where the address must be put. + */ +#define RECORD_CUR_BYTE_ADDR(a_tknzr, a_addr) \ +status = cr_input_get_cur_byte_addr \ + (PRIVATE (a_tknzr)->input, a_addr) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Peeks a byte from the topmost parser input at + *a given offset from the current position. + *If it fails, goto the "error:" label. + * + *@param a_parser the current instance of #CRTknzr. + *@param a_offset the offset of the byte to peek, the + *current byte having the offset '0'. + *@param a_byte_ptr out parameter a pointer (guchar*) to + *where the peeked char is to be stored. + */ +#define PEEK_BYTE(a_tknzr, a_offset, a_byte_ptr) \ +status = cr_tknzr_peek_byte (a_tknzr, \ + a_offset, \ + a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +#define BYTE(a_input, a_n, a_eof) \ +cr_input_peek_byte2 (a_input, a_n, a_eof) + +/** + *Reads a byte from the topmost parser input + *steam. + *If it fails, goto the "error" label. + *@param a_parser the current instance of #CRTknzr. + *@param a_byte_ptr the guchar * where to put the read char. + */ +#define READ_NEXT_BYTE(a_tknzr, a_byte_ptr) \ +status = \ +cr_input_read_byte (PRIVATE (a_tknzr)->input, a_byte_ptr) ;\ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skips a given number of byte in the topmost + *parser input. Don't update line and column number. + *In case of error, jumps to the "error:" label + *of the surrounding function. + *@param a_parser the current instance of #CRTknzr. + *@param a_nb_bytes the number of bytes to skip. + */ +#define SKIP_BYTES(a_tknzr, a_nb_bytes) \ +status = cr_input_seek_index (PRIVATE (a_tknzr)->input, \ + CR_SEEK_CUR, a_nb_bytes) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skip utf8 encoded characters. + *Updates line and column numbers. + *@param a_parser the current instance of #CRTknzr. + *@param a_nb_chars the number of chars to skip. Must be of + *type glong. + */ +#define SKIP_CHARS(a_tknzr, a_nb_chars) \ +{ \ +gulong nb_chars = a_nb_chars ; \ +status = cr_input_consume_chars \ + (PRIVATE (a_tknzr)->input,0, &nb_chars) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; \ +} + +/** + *Tests the condition and if it is false, sets + *status to "CR_PARSING_ERROR" and goto the 'error' + *label. + *@param condition the condition to test. + */ +#define ENSURE_PARSING_COND(condition) \ +if (! (condition)) {status = CR_PARSING_ERROR; goto error ;} + +static enum CRStatus cr_tknzr_parse_nl (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_w (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) ; + +static enum CRStatus cr_tknzr_parse_unicode_escape (CRTknzr * a_this, + guint32 * a_unicode, + CRParsingLocation *a_location) ; + +static enum CRStatus cr_tknzr_parse_escape (CRTknzr * a_this, + guint32 * a_esc_code, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_string (CRTknzr * a_this, + CRString ** a_str); + +static enum CRStatus cr_tknzr_parse_comment (CRTknzr * a_this, + CRString ** a_comment); + +static enum CRStatus cr_tknzr_parse_nmstart (CRTknzr * a_this, + guint32 * a_char, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_num (CRTknzr * a_this, + CRNum ** a_num); + +/********************************** + *PRIVATE methods + **********************************/ + +/** + *Parses a "w" as defined by the css spec at [4.1.1]: + * w ::= [ \t\r\n\f]* + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. Upon successful completion, points + *to the beginning of the parsed white space, points to NULL otherwise. + *Can also point to NULL is there is no white space actually. + *@param a_end out param. Upon successful completion, points + *to the end of the parsed white space, points to NULL otherwise. + *Can also point to NULL is there is no white space actually. + */ +static enum CRStatus +cr_tknzr_parse_w (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_start && a_end, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + *a_start = NULL; + *a_end = NULL; + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cr_utils_is_white_space (cur_char) == FALSE) { + status = CR_PARSING_ERROR; + goto error; + } + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + RECORD_CUR_BYTE_ADDR (a_this, a_start); + *a_end = *a_start; + + for (;;) { + gboolean is_eof = FALSE; + + cr_input_get_end_of_file (PRIVATE (a_this)->input, &is_eof); + if (is_eof) + break; + + status = cr_tknzr_peek_char (a_this, &cur_char); + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + break; + } else if (status != CR_OK) { + goto error; + } + + if (cr_utils_is_white_space (cur_char) == TRUE) { + READ_NEXT_CHAR (a_this, &cur_char); + RECORD_CUR_BYTE_ADDR (a_this, a_end); + } else { + break; + } + } + + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses a newline as defined in the css2 spec: + * nl ::= \n|\r\n|\r|\f + * + *@param a_this the "this pointer" of the current instance of #CRTknzr. + *@param a_start a pointer to the first character of the successfully + *parsed string. + *@param a_end a pointer to the last character of the successfully parsed + *string. + *@result CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nl (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) +{ + CRInputPos init_pos; + guchar next_chars[2] = { 0 }; + enum CRStatus status = CR_PARSING_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_start && a_end, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_chars[0]); + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if ((next_chars[0] == '\r' && next_chars[1] == '\n')) { + SKIP_BYTES (a_this, 1); + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + SKIP_CHARS (a_this, 1); + + RECORD_CUR_BYTE_ADDR (a_this, a_end); + + status = CR_OK; + } else if (next_chars[0] == '\n' + || next_chars[0] == '\r' || next_chars[0] == '\f') { + SKIP_CHARS (a_this, 1); + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + RECORD_CUR_BYTE_ADDR (a_this, a_start); + *a_end = *a_start; + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + return CR_OK ; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos) ; + return status; +} + +/** + *Go ahead in the parser input, skipping all the spaces. + *If the next char if not a white space, this function does nothing. + *In any cases, it stops when it encounters a non white space character. + * + *@param a_this the current instance of #CRTknzr. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_try_to_skip_spaces (CRTknzr * a_this) +{ + enum CRStatus status = CR_ERROR; + guint32 cur_char = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + status = cr_input_peek_char (PRIVATE (a_this)->input, &cur_char); + + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) + return CR_OK; + return status; + } + + if (cr_utils_is_white_space (cur_char) == TRUE) { + gulong nb_chars = -1; /*consume all spaces */ + + status = cr_input_consume_white_spaces + (PRIVATE (a_this)->input, &nb_chars); + } + + return status; +} + +/** + *Parses a "comment" as defined in the css spec at [4.1.1]: + *COMMENT ::= \/\*[^*]*\*+([^/][^*]*\*+)*\/ . + *This complex regexp is just to say that comments start + *with the two chars '/''*' and ends with the two chars '*''/'. + *It also means that comments cannot be nested. + *So based on that, I've just tried to implement the parsing function + *simply and in a straight forward manner. + */ +static enum CRStatus +cr_tknzr_parse_comment (CRTknzr * a_this, + CRString ** a_comment) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, next_char= 0; + CRString *comment = NULL; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char) ; + ENSURE_PARSING_COND (cur_char == '/'); + cr_tknzr_get_parsing_location (a_this, &loc) ; + + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '*'); + comment = cr_string_new (); + for (;;) { /* [^*]* */ + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == '*') + break; + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (comment->stryng, cur_char); + } + /* Stop condition: next_char == '*' */ + for (;;) { /* \*+ */ + READ_NEXT_CHAR(a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '*'); + g_string_append_unichar (comment->stryng, cur_char); + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char != '*') + break; + } + /* Stop condition: next_char != '*' */ + for (;;) { /* ([^/][^*]*\*+)* */ + if (next_char == '/') + break; + READ_NEXT_CHAR(a_this, &cur_char); + g_string_append_unichar (comment->stryng, cur_char); + for (;;) { /* [^*]* */ + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == '*') + break; + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (comment->stryng, cur_char); + } + /* Stop condition: next_char = '*', no need to verify, because peek and read exit to error anyway */ + for (;;) { /* \*+ */ + READ_NEXT_CHAR(a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '*'); + g_string_append_unichar (comment->stryng, cur_char); + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char != '*') + break; + } + /* Continue condition: next_char != '*' */ + } + /* Stop condition: next_char == '\/' */ + READ_NEXT_CHAR(a_this, &cur_char); + g_string_append_unichar (comment->stryng, cur_char); + + if (status == CR_OK) { + cr_parsing_location_copy (&comment->location, + &loc) ; + *a_comment = comment; + return CR_OK; + } + error: + + if (comment) { + cr_string_destroy (comment); + comment = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses an 'unicode' escape sequence defined + *in css spec at chap 4.1.1: + *unicode ::= \\[0-9a-f]{1,6}[ \n\r\t\f]? + *@param a_this the current instance of #CRTknzr. + *@param a_start out parameter. A pointer to the start + *of the unicode escape sequence. Must *NOT* be deleted by + *the caller. + *@param a_end out parameter. A pointer to the last character + *of the unicode escape sequence. Must *NOT* be deleted by the caller. + *@return CR_OK if parsing succeeded, an error code otherwise. + *Error code can be either CR_PARSING_ERROR if the string + *parsed just doesn't + *respect the production or another error if a + *lower level error occurred. + */ +static enum CRStatus +cr_tknzr_parse_unicode_escape (CRTknzr * a_this, + guint32 * a_unicode, + CRParsingLocation *a_location) +{ + guint32 cur_char; + CRInputPos init_pos; + glong occur = 0; + guint32 unicode = 0; + guchar *tmp_char_ptr1 = NULL, + *tmp_char_ptr2 = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_unicode, CR_BAD_PARAM_ERROR); + + /*first, let's backup the current position pointer */ + RECORD_INITIAL_POS (a_this, &init_pos); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != '\\') { + status = CR_PARSING_ERROR; + goto error; + } + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + PEEK_NEXT_CHAR (a_this, &cur_char); + + for (occur = 0, unicode = 0; ((cur_char >= '0' && cur_char <= '9') + || (cur_char >= 'a' && cur_char <= 'f') + || (cur_char >= 'A' && cur_char <= 'F')) + && occur < 6; occur++) { + gint cur_char_val = 0; + + READ_NEXT_CHAR (a_this, &cur_char); + + if ((cur_char >= '0' && cur_char <= '9')) { + cur_char_val = (cur_char - '0'); + } else if ((cur_char >= 'a' && cur_char <= 'f')) { + cur_char_val = 10 + (cur_char - 'a'); + } else if ((cur_char >= 'A' && cur_char <= 'F')) { + cur_char_val = 10 + (cur_char - 'A'); + } + + unicode = unicode * 16 + cur_char_val; + + PEEK_NEXT_CHAR (a_this, &cur_char); + } + + /* Eat a whitespace if possible. */ + cr_tknzr_parse_w (a_this, &tmp_char_ptr1, + &tmp_char_ptr2, NULL); + *a_unicode = unicode; + return CR_OK; + + error: + /* + *restore the initial position pointer backuped at + *the beginning of this function. + */ + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *parses an escape sequence as defined by the css spec: + *escape ::= {unicode}|\\[ -~\200-\4177777] + *@param a_this the current instance of #CRTknzr . + */ +static enum CRStatus +cr_tknzr_parse_escape (CRTknzr * a_this, guint32 * a_esc_code, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + guint32 cur_char = 0; + CRInputPos init_pos; + guchar next_chars[2]; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_esc_code, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_chars[0]); + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if (next_chars[0] != '\\') { + status = CR_PARSING_ERROR; + goto error; + } + + if ((next_chars[1] >= '0' && next_chars[1] <= '9') + || (next_chars[1] >= 'a' && next_chars[1] <= 'f') + || (next_chars[1] >= 'A' && next_chars[1] <= 'F')) { + status = cr_tknzr_parse_unicode_escape (a_this, a_esc_code, + a_location); + } else { + /*consume the '\' char */ + READ_NEXT_CHAR (a_this, &cur_char); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + /*then read the char after the '\' */ + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != ' ' && (cur_char < 200 || cur_char > 4177777)) { + status = CR_PARSING_ERROR; + goto error; + } + *a_esc_code = cur_char; + + } + if (status == CR_OK) { + return CR_OK; + } + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses a string type as defined in css spec [4.1.1]: + * + *string ::= {string1}|{string2} + *string1 ::= \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" + *string2 ::= \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out parameter. Upon successful completion, + *points to the beginning of the string, points to an undefined value + *otherwise. + *@param a_end out parameter. Upon successful completion, points to + *the beginning of the string, points to an undefined value otherwise. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_string (CRTknzr * a_this, CRString ** a_str) +{ + guint32 cur_char = 0, + delim = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + CRString *str = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char == '"') + delim = '"'; + else if (cur_char == '\'') + delim = '\''; + else { + status = CR_PARSING_ERROR; + goto error; + } + str = cr_string_new (); + if (str) { + cr_tknzr_get_parsing_location + (a_this, &str->location) ; + } + for (;;) { + guchar next_chars[2] = { 0 }; + + PEEK_BYTE (a_this, 1, &next_chars[0]); + + if (next_chars[0] == '\\') { + guchar *tmp_char_ptr1 = NULL, + *tmp_char_ptr2 = NULL; + guint32 esc_code = 0; + + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if (next_chars[1] == '\'' || next_chars[1] == '"' || next_chars[1] == '\\') { + g_string_append_unichar (str->stryng, + next_chars[1]); + SKIP_BYTES (a_this, 2); + status = CR_OK; + } else { + status = cr_tknzr_parse_escape + (a_this, &esc_code, NULL); + + if (status == CR_OK) { + g_string_append_unichar + (str->stryng, + esc_code); + } + } + + if (status != CR_OK) { + /* + *consume the '\' char, and try to parse + *a newline. + */ + READ_NEXT_CHAR (a_this, &cur_char); + + status = cr_tknzr_parse_nl + (a_this, &tmp_char_ptr1, + &tmp_char_ptr2, NULL); + } + + CHECK_PARSING_STATUS (status, FALSE); + } else if (next_chars[0] == delim) { + READ_NEXT_CHAR (a_this, &cur_char); + break; + } else if (next_chars[0] == '\t' + || (next_chars[0] >= ' ' && next_chars[0] <= '~')) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (str->stryng, + cur_char); + status = CR_OK; + } + + else if (cr_utils_is_nonascii (next_chars[0])) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (str->stryng, cur_char); + } else { + status = CR_PARSING_ERROR; + goto error; + } + } + + if (status == CR_OK) { + if (*a_str == NULL) { + *a_str = str; + str = NULL; + } else { + (*a_str)->stryng = g_string_append_len + ((*a_str)->stryng, + str->stryng->str, + str->stryng->len); + cr_string_destroy (str); + } + return CR_OK; + } + + error: + + if (str) { + cr_string_destroy (str) ; + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses the an nmstart as defined by the css2 spec [4.1.1]: + * nmstart [a-zA-Z]|{nonascii}|{escape} + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. A pointer to the starting point of + *the token. + *@param a_end out param. A pointer to the ending point of the + *token. + *@param a_char out param. The actual parsed nmchar. + *@return CR_OK upon successful completion, + *an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nmstart (CRTknzr * a_this, + guint32 * a_char, + CRParsingLocation *a_location) +{ + CRInputPos init_pos; + enum CRStatus status = CR_OK; + guint32 cur_char = 0, + next_char = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '\\') { + status = cr_tknzr_parse_escape (a_this, a_char, + a_location); + + if (status != CR_OK) + goto error; + + } else if (cr_utils_is_nonascii (next_char) == TRUE + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z')) + ) { + READ_NEXT_CHAR (a_this, &cur_char); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + *a_char = cur_char; + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; + +} + +/** + *Parses an nmchar as described in the css spec at + *chap 4.1.1: + *nmchar ::= [a-z0-9-]|{nonascii}|{escape} + * + *Humm, I have added the possibility for nmchar to + *contain upper case letters. + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. A pointer to the starting point of + *the token. + *@param a_end out param. A pointer to the ending point of the + *token. + *@param a_char out param. The actual parsed nmchar. + *@return CR_OK upon successful completion, + *an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nmchar (CRTknzr * a_this, guint32 * a_char, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0, + next_char = 0; + enum CRStatus status = CR_OK; + CRInputPos init_pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_char, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_input_peek_char (PRIVATE (a_this)->input, + &next_char) ; + if (status != CR_OK) + goto error; + + if (next_char == '\\') { + status = cr_tknzr_parse_escape (a_this, a_char, + a_location); + + if (status != CR_OK) + goto error; + + } else if (cr_utils_is_nonascii (next_char) == TRUE + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z')) + || ((next_char >= '0') && (next_char <= '9')) + || (next_char == '-') + || (next_char == '_') /*'_' not allowed by the spec. */ + ) { + READ_NEXT_CHAR (a_this, &cur_char); + *a_char = cur_char; + status = CR_OK; + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + } else { + status = CR_PARSING_ERROR; + goto error; + } + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses an "ident" as defined in css spec [4.1.1]: + *ident ::= {nmstart}{nmchar}* + * + *Actually parses it using the css3 grammar: + *ident ::= -?{nmstart}{nmchar}* + *@param a_this the currens instance of #CRTknzr. + * + *@param a_str a pointer to parsed ident. If *a_str is NULL, + *this function allocates a new instance of CRString. If not, + *the function just appends the parsed string to the one passed. + *In both cases it is up to the caller to free *a_str. + * + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +static enum CRStatus +cr_tknzr_parse_ident (CRTknzr * a_this, CRString ** a_str) +{ + guint32 tmp_char = 0; + CRString *stringue = NULL ; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean location_is_set = FALSE ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + PEEK_NEXT_CHAR (a_this, &tmp_char) ; + stringue = cr_string_new () ; + g_return_val_if_fail (stringue, + CR_OUT_OF_MEMORY_ERROR) ; + + if (tmp_char == '-') { + READ_NEXT_CHAR (a_this, &tmp_char) ; + cr_tknzr_get_parsing_location + (a_this, &stringue->location) ; + location_is_set = TRUE ; + g_string_append_unichar (stringue->stryng, + tmp_char) ; + } + status = cr_tknzr_parse_nmstart (a_this, &tmp_char, NULL); + if (status != CR_OK) { + status = CR_PARSING_ERROR; + goto end ; + } + if (location_is_set == FALSE) { + cr_tknzr_get_parsing_location + (a_this, &stringue->location) ; + location_is_set = TRUE ; + } + g_string_append_unichar (stringue->stryng, tmp_char); + for (;;) { + status = cr_tknzr_parse_nmchar (a_this, + &tmp_char, + NULL); + if (status != CR_OK) { + status = CR_OK ; + break; + } + g_string_append_unichar (stringue->stryng, tmp_char); + } + if (status == CR_OK) { + if (!*a_str) { + *a_str = stringue ; + + } else { + g_string_append_len ((*a_str)->stryng, + stringue->stryng->str, + stringue->stryng->len) ; + cr_string_destroy (stringue) ; + } + stringue = NULL ; + } + + error: + end: + if (stringue) { + cr_string_destroy (stringue) ; + stringue = NULL ; + } + if (status != CR_OK ) { + cr_tknzr_set_cur_pos (a_this, &init_pos) ; + } + return status ; +} + + +/** + *Parses a "name" as defined by css spec [4.1.1]: + *name ::= {nmchar}+ + * + *@param a_this the current instance of #CRTknzr. + * + *@param a_str out parameter. A pointer to the successfully parsed + *name. If *a_str is set to NULL, this function allocates a new instance + *of CRString. If not, it just appends the parsed name to the passed *a_str. + *In both cases, it is up to the caller to free *a_str. + * + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_name (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 tmp_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean str_needs_free = FALSE, + is_first_nmchar=TRUE ; + glong i = 0; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, + CR_BAD_PARAM_ERROR) ; + + RECORD_INITIAL_POS (a_this, &init_pos); + + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + for (i = 0;; i++) { + if (is_first_nmchar == TRUE) { + status = cr_tknzr_parse_nmchar + (a_this, &tmp_char, + &loc) ; + is_first_nmchar = FALSE ; + } else { + status = cr_tknzr_parse_nmchar + (a_this, &tmp_char, NULL) ; + } + if (status != CR_OK) + break; + g_string_append_unichar ((*a_str)->stryng, + tmp_char); + } + if (i > 0) { + cr_parsing_location_copy + (&(*a_str)->location, &loc) ; + return CR_OK; + } + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return CR_PARSING_ERROR; +} + +/** + *Parses a "hash" as defined by the css spec in [4.1.1]: + *HASH ::= #{name} + */ +static enum CRStatus +cr_tknzr_parse_hash (CRTknzr * a_this, CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean str_needs_free = FALSE; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + if (cur_char != '#') { + status = CR_PARSING_ERROR; + goto error; + } + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + cr_tknzr_get_parsing_location (a_this, + &loc) ; + status = cr_tknzr_parse_name (a_this, a_str); + cr_parsing_location_copy (&(*a_str)->location, &loc) ; + if (status != CR_OK) { + goto error; + } + return CR_OK; + + error: + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses an uri as defined by the css spec [4.1.1]: + * URI ::= url\({w}{string}{w}\) + * |url\({w}([!#$%&*-~]|{nonascii}|{escape})*{w}\) + * + *@param a_this the current instance of #CRTknzr. + *@param a_str the successfully parsed url. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_uri (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_PARSING_ERROR; + guchar tab[4] = { 0 }, *tmp_ptr1 = NULL, *tmp_ptr2 = NULL; + CRString *str = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &tab[0]); + PEEK_BYTE (a_this, 2, &tab[1]); + PEEK_BYTE (a_this, 3, &tab[2]); + PEEK_BYTE (a_this, 4, &tab[3]); + + if (tab[0] != 'u' || tab[1] != 'r' || tab[2] != 'l' || tab[3] != '(') { + status = CR_PARSING_ERROR; + goto error; + } + /* + *Here, we want to skip 4 bytes ('u''r''l''('). + *But we also need to keep track of the parsing location + *of the 'u'. So, we skip 1 byte, we record the parsing + *location, then we skip the 3 remaining bytes. + */ + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, &location) ; + SKIP_CHARS (a_this, 3); + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_string (a_this, a_str); + + if (status == CR_OK) { + guint32 next_char = 0; + status = cr_tknzr_parse_w (a_this, &tmp_ptr1, + &tmp_ptr2, NULL); + cr_tknzr_try_to_skip_spaces (a_this); + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == ')') { + READ_NEXT_CHAR (a_this, &cur_char); + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + } + } + if (status != CR_OK) { + str = cr_string_new (); + for (;;) { + guint32 next_char = 0; + PEEK_NEXT_CHAR (a_this, &next_char); + if (strchr ("!#$%&", next_char) + || (next_char >= '*' && next_char <= '~') + || (cr_utils_is_nonascii (next_char) == TRUE)) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar + (str->stryng, cur_char); + status = CR_OK; + } else { + guint32 esc_code = 0; + status = cr_tknzr_parse_escape + (a_this, &esc_code, NULL); + if (status == CR_OK) { + g_string_append_unichar + (str->stryng, + esc_code); + } else { + status = CR_OK; + break; + } + } + } + cr_tknzr_try_to_skip_spaces (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + if (cur_char == ')') { + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + if (str) { + if (*a_str == NULL) { + *a_str = str; + str = NULL; + } else { + g_string_append_len + ((*a_str)->stryng, + str->stryng->str, + str->stryng->len); + cr_string_destroy (str); + } + } + } + + cr_parsing_location_copy + (&(*a_str)->location, + &location) ; + return CR_OK ; + error: + if (str) { + cr_string_destroy (str); + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *parses an RGB as defined in the css2 spec. + *rgb: rgb '('S*{num}%?S* ',' {num}#?S*,S*{num}#?S*')' + * + *@param a_this the "this pointer" of the current instance of + *@param a_rgb out parameter the parsed rgb. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_rgb (CRTknzr * a_this, CRRgb ** a_rgb) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRNum *num = NULL; + guchar next_bytes[3] = { 0 }, cur_byte = 0; + glong red = 0, + green = 0, + blue = 0, + i = 0; + gboolean is_percentage = FALSE; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + PEEK_BYTE (a_this, 2, &next_bytes[1]); + PEEK_BYTE (a_this, 3, &next_bytes[2]); + + if (((next_bytes[0] == 'r') || (next_bytes[0] == 'R')) + && ((next_bytes[1] == 'g') || (next_bytes[1] == 'G')) + && ((next_bytes[2] == 'b') || (next_bytes[2] == 'B'))) { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, &location) ; + SKIP_CHARS (a_this, 2); + } else { + status = CR_PARSING_ERROR; + goto error; + } + READ_NEXT_BYTE (a_this, &cur_byte); + ENSURE_PARSING_COND (cur_byte == '('); + + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_num (a_this, &num); + ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL)); + + red = (glong)num->val; + cr_num_destroy (num); + num = NULL; + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + if (next_bytes[0] == '%') { + SKIP_CHARS (a_this, 1); + is_percentage = TRUE; + } + cr_tknzr_try_to_skip_spaces (a_this); + + for (i = 0; i < 2; i++) { + READ_NEXT_BYTE (a_this, &cur_byte); + ENSURE_PARSING_COND (cur_byte == ','); + + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_num (a_this, &num); + ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL)); + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + if (next_bytes[0] == '%') { + SKIP_CHARS (a_this, 1); + is_percentage = 1; + } + + if (i == 0) { + green = (glong)num->val; + } else if (i == 1) { + blue = (glong)num->val; + } + + if (num) { + cr_num_destroy (num); + num = NULL; + } + cr_tknzr_try_to_skip_spaces (a_this); + } + + READ_NEXT_BYTE (a_this, &cur_byte); + if (*a_rgb == NULL) { + *a_rgb = cr_rgb_new_with_vals (red, green, blue, + is_percentage); + + if (*a_rgb == NULL) { + status = CR_ERROR; + goto error; + } + status = CR_OK; + } else { + (*a_rgb)->red = red; + (*a_rgb)->green = green; + (*a_rgb)->blue = blue; + (*a_rgb)->is_percentage = is_percentage; + + status = CR_OK; + } + + if (status == CR_OK) { + if (a_rgb && *a_rgb) { + cr_parsing_location_copy + (&(*a_rgb)->location, + &location) ; + } + return CR_OK; + } + + error: + if (num) { + cr_num_destroy (num); + num = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + return CR_OK; +} + +/** + *Parses a atkeyword as defined by the css spec in [4.1.1]: + *ATKEYWORD ::= @{ident} + * + *@param a_this the "this pointer" of the current instance of + *#CRTknzr. + * + *@param a_str out parameter. The parsed atkeyword. If *a_str is + *set to NULL this function allocates a new instance of CRString and + *sets it to the parsed atkeyword. If not, this function just appends + *the parsed atkeyword to the end of *a_str. In both cases it is up to + *the caller to free *a_str. + * + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_atkeyword (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + gboolean str_needs_free = FALSE; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != '@') { + status = CR_PARSING_ERROR; + goto error; + } + + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + status = cr_tknzr_parse_ident (a_this, a_str); + if (status != CR_OK) { + goto error; + } + return CR_OK; + error: + + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +static enum CRStatus +cr_tknzr_parse_important (CRTknzr * a_this, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '!'); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + cr_tknzr_try_to_skip_spaces (a_this); + + if (BYTE (PRIVATE (a_this)->input, 1, NULL) == 'i' + && BYTE (PRIVATE (a_this)->input, 2, NULL) == 'm' + && BYTE (PRIVATE (a_this)->input, 3, NULL) == 'p' + && BYTE (PRIVATE (a_this)->input, 4, NULL) == 'o' + && BYTE (PRIVATE (a_this)->input, 5, NULL) == 'r' + && BYTE (PRIVATE (a_this)->input, 6, NULL) == 't' + && BYTE (PRIVATE (a_this)->input, 7, NULL) == 'a' + && BYTE (PRIVATE (a_this)->input, 8, NULL) == 'n' + && BYTE (PRIVATE (a_this)->input, 9, NULL) == 't') { + SKIP_BYTES (a_this, 9); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + return CR_OK; + } else { + status = CR_PARSING_ERROR; + } + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses a num as defined in the css spec [4.1.1]: + *[0-9]+|[0-9]*\.[0-9]+ + *@param a_this the current instance of #CRTknzr. + *@param a_num out parameter. The parsed number. + *@return CR_OK upon successful completion, + *an error code otherwise. + * + *The CSS specification says that numbers may be + *preceded by '+' or '-' to indicate the sign. + *Technically, the "num" construction as defined + *by the tokenizer doesn't allow this, but we parse + *it here for simplicity. + */ +static enum CRStatus +cr_tknzr_parse_num (CRTknzr * a_this, + CRNum ** a_num) +{ + enum CRStatus status = CR_PARSING_ERROR; + enum CRNumType val_type = NUM_GENERIC; + gboolean parsing_dec, /* true iff seen decimal point. */ + parsed, /* true iff the substring seen so far is a valid CSS + number, i.e. `[0-9]+|[0-9]*\.[0-9]+'. */ + parsing_exp = FALSE; /* true if seen an exponential */ + gdouble exponent = 0; /* Start off the exponent at 0 */ + int exp_sign = 1; + guint32 cur_char = 0, + next_char = 0; + gdouble numerator, denominator = 1; + CRInputPos init_pos; + CRParsingLocation location = {0,0,0}; + int sign = 1; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char == '+' || cur_char == '-') { + if (cur_char == '-') { + sign = -1; + } + READ_NEXT_CHAR (a_this, &cur_char); + } + + if (IS_NUM (cur_char)) { + numerator = (cur_char - '0'); + parsing_dec = FALSE; + parsed = TRUE; + } else if (cur_char == '.') { + numerator = 0; + parsing_dec = TRUE; + parsed = FALSE; + } else { + status = CR_PARSING_ERROR; + goto error; + } + cr_tknzr_get_parsing_location (a_this, &location) ; + + for (;;) { + status = cr_tknzr_peek_char (a_this, &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) + status = CR_OK; + break; + } + if (next_char == '.') { + if (parsing_dec) { + status = CR_PARSING_ERROR; + goto error; + } + + READ_NEXT_CHAR (a_this, &cur_char); + parsing_dec = TRUE; + parsed = FALSE; /* In CSS, there must be at least + one digit after `.'. */ + } else if (!parsing_exp && (next_char == 'E' || next_char == 'e') && parsed) { + guchar next_byte; + PEEK_BYTE (a_this, 2, &next_byte) + if (next_byte == '+') { + READ_NEXT_CHAR (a_this, &cur_char); + } else if (next_byte == '-') { + exp_sign = -1; + READ_NEXT_CHAR (a_this, &cur_char); + } else if (!IS_NUM (next_byte)) { + break; + } + + READ_NEXT_CHAR (a_this, &cur_char); + parsing_exp = TRUE; + parsed = FALSE; + } else if (IS_NUM (next_char)) { + READ_NEXT_CHAR (a_this, &cur_char); + parsed = TRUE; + + if (parsing_exp) { + exponent = exponent * 10 + (cur_char - '0'); + } else { + numerator = numerator * 10 + (cur_char - '0'); + if (parsing_dec) { + denominator *= 10; + } + } + } else { + break; + } + } + + if (!parsed) { + status = CR_PARSING_ERROR; + } + + /* + *Now, set the output param values. + */ + if (status == CR_OK) { + gdouble val = ((numerator / denominator) * sign) * pow(10, exponent * exp_sign); + if (*a_num == NULL) { + *a_num = cr_num_new_with_val (val, val_type); + + if (*a_num == NULL) { + status = CR_ERROR; + goto error; + } + } else { + (*a_num)->val = val; + (*a_num)->type = val_type; + } + cr_parsing_location_copy (&(*a_num)->location, + &location) ; + return CR_OK; + } + + error: + + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/********************************************* + *PUBLIC methods + ********************************************/ + +CRTknzr * +cr_tknzr_new (CRInput * a_input) +{ + CRTknzr *result = NULL; + + result = (CRTknzr *) g_try_malloc (sizeof (CRTknzr)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRTknzr)); + + result->priv = (CRTknzrPriv *)g_try_malloc (sizeof (CRTknzrPriv)); + + if (result->priv == NULL) { + cr_utils_trace_info ("Out of memory"); + + if (result) { + g_free (result); + result = NULL; + } + + return NULL; + } + memset (result->priv, 0, sizeof (CRTknzrPriv)); + if (a_input) + cr_tknzr_set_input (result, a_input); + return result; +} + +CRTknzr * +cr_tknzr_new_from_buf (guchar * a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_at_destroy) +{ + CRTknzr *result = NULL; + CRInput *input = NULL; + + input = cr_input_new_from_buf (a_buf, a_len, a_enc, + a_free_at_destroy); + + g_return_val_if_fail (input != NULL, NULL); + + result = cr_tknzr_new (input); + + return result; +} + +CRTknzr * +cr_tknzr_new_from_uri (const guchar * a_file_uri, + enum CREncoding a_enc) +{ + CRTknzr *result = NULL; + CRInput *input = NULL; + + input = cr_input_new_from_uri ((const gchar *) a_file_uri, a_enc); + g_return_val_if_fail (input != NULL, NULL); + + result = cr_tknzr_new (input); + + return result; +} + +void +cr_tknzr_ref (CRTknzr * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +gboolean +cr_tknzr_unref (CRTknzr * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), FALSE); + + if (PRIVATE (a_this)->ref_count > 0) { + PRIVATE (a_this)->ref_count--; + } + + if (PRIVATE (a_this)->ref_count == 0) { + cr_tknzr_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +enum CRStatus +cr_tknzr_set_input (CRTknzr * a_this, CRInput * a_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->input) { + cr_input_unref (PRIVATE (a_this)->input); + } + + PRIVATE (a_this)->input = a_input; + + cr_input_ref (PRIVATE (a_this)->input); + + return CR_OK; +} + +enum CRStatus +cr_tknzr_get_input (CRTknzr * a_this, CRInput ** a_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + *a_input = PRIVATE (a_this)->input; + + return CR_OK; +} + +/********************************* + *Tokenizer input handling routines + *********************************/ + +/** + *Reads the next byte from the parser input stream. + *@param a_this the "this pointer" of the current instance of + *#CRParser. + *@param a_byte out parameter the place where to store the byte + *read. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_tknzr_read_byte (CRTknzr * a_this, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + return cr_input_read_byte (PRIVATE (a_this)->input, a_byte); + +} + +/** + *Reads the next char from the parser input stream. + *@param a_this the current instance of #CRTknzr. + *@param a_char out parameter. The read char. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_tknzr_read_char (CRTknzr * a_this, guint32 * a_char) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_read_char (PRIVATE (a_this)->input, a_char); +} + +/** + *Peeks a char from the parser input stream. + *To "peek a char" means reads the next char without consuming it. + *Subsequent calls to this function return the same char. + *@param a_this the current instance of #CRTknzr. + *@param a_char out parameter. The peeked char upon successful completion. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_tknzr_peek_char (CRTknzr * a_this, guint32 * a_char) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_peek_char (PRIVATE (a_this)->input, a_char); +} + +/** + *Peeks a byte ahead at a given position in the parser input stream. + *@param a_this the current instance of #CRTknzr. + *@param a_offset the offset of the peeked byte starting from the current + *byte in the parser input stream. + *@param a_byte out parameter. The peeked byte upon + *successful completion. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_tknzr_peek_byte (CRTknzr * a_this, gulong a_offset, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input && a_byte, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_peek_byte (PRIVATE (a_this)->input, + CR_SEEK_CUR, a_offset, a_byte); +} + +/** + *Same as cr_tknzr_peek_byte() but this api returns the byte peeked. + *@param a_this the current instance of #CRTknzr. + *@param a_offset the offset of the peeked byte starting from the current + *byte in the parser input stream. + *@param a_eof out parameter. If not NULL, is set to TRUE if we reached end of + *file, FALE otherwise. If the caller sets it to NULL, this parameter + *is just ignored. + *@return the peeked byte. + */ +guchar +cr_tknzr_peek_byte2 (CRTknzr * a_this, gulong a_offset, gboolean * a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, 0); + + return cr_input_peek_byte2 (PRIVATE (a_this)->input, a_offset, a_eof); +} + +/** + *Gets the number of bytes left in the topmost input stream + *associated to this parser. + *@param a_this the current instance of #CRTknzr + *@return the number of bytes left or -1 in case of error. + */ +glong +cr_tknzr_get_nb_bytes_left (CRTknzr * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_nb_bytes_left (PRIVATE (a_this)->input); +} + +enum CRStatus +cr_tknzr_get_cur_pos (CRTknzr * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_pos, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_cur_pos (PRIVATE (a_this)->input, a_pos); +} + +enum CRStatus +cr_tknzr_get_parsing_location (CRTknzr *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, + CR_BAD_PARAM_ERROR) ; + + return cr_input_get_parsing_location + (PRIVATE (a_this)->input, a_loc) ; +} + +enum CRStatus +cr_tknzr_get_cur_byte_addr (CRTknzr * a_this, guchar ** a_addr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_cur_byte_addr (PRIVATE (a_this)->input, a_addr); +} + +enum CRStatus +cr_tknzr_seek_index (CRTknzr * a_this, enum CRSeekPos a_origin, gint a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_seek_index (PRIVATE (a_this)->input, a_origin, a_pos); +} + +enum CRStatus +cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char) +{ + gulong consumed = *(gulong *) a_nb_char; + enum CRStatus status; + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + status = cr_input_consume_chars (PRIVATE (a_this)->input, + a_char, &consumed); + *a_nb_char = (glong) consumed; + return status; +} + +enum CRStatus +cr_tknzr_set_cur_pos (CRTknzr * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_set_cur_pos (PRIVATE (a_this)->input, a_pos); +} + +enum CRStatus +cr_tknzr_unget_token (CRTknzr * a_this, CRToken * a_token) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->token_cache == NULL, + CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->token_cache = a_token; + + return CR_OK; +} + +/** + *Returns the next token of the input stream. + *This method is really central. Each parsing + *method calls it. + *@param a_this the current tokenizer. + *@param a_tk out parameter. The returned token. + *for the sake of mem leak avoidance, *a_tk must + *be NULL. + *@param CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_tknzr_get_next_token (CRTknzr * a_this, CRToken ** a_tk) +{ + enum CRStatus status = CR_OK; + CRToken *token = NULL; + CRInputPos init_pos; + guint32 next_char = 0; + guchar next_bytes[4] = { 0 }; + gboolean reached_eof = FALSE; + CRInput *input = NULL; + CRString *str = NULL; + CRRgb *rgb = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_tk && *a_tk == NULL + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + *a_tk = PRIVATE (a_this)->token_cache; + PRIVATE (a_this)->token_cache = NULL; + return CR_OK; + } + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_input_get_end_of_file + (PRIVATE (a_this)->input, &reached_eof); + ENSURE_PARSING_COND (status == CR_OK); + + if (reached_eof == TRUE) { + status = CR_END_OF_INPUT_ERROR; + goto error; + } + + input = PRIVATE (a_this)->input; + + PEEK_NEXT_CHAR (a_this, &next_char); + token = cr_token_new (); + ENSURE_PARSING_COND (token); + + switch (next_char) { + case '@': + { + if (BYTE (input, 2, NULL) == 'f' + && BYTE (input, 3, NULL) == 'o' + && BYTE (input, 4, NULL) == 'n' + && BYTE (input, 5, NULL) == 't' + && BYTE (input, 6, NULL) == '-' + && BYTE (input, 7, NULL) == 'f' + && BYTE (input, 8, NULL) == 'a' + && BYTE (input, 9, NULL) == 'c' + && BYTE (input, 10, NULL) == 'e') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 9); + status = cr_token_set_font_face_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'c' + && BYTE (input, 3, NULL) == 'h' + && BYTE (input, 4, NULL) == 'a' + && BYTE (input, 5, NULL) == 'r' + && BYTE (input, 6, NULL) == 's' + && BYTE (input, 7, NULL) == 'e' + && BYTE (input, 8, NULL) == 't') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 7); + status = cr_token_set_charset_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'i' + && BYTE (input, 3, NULL) == 'm' + && BYTE (input, 4, NULL) == 'p' + && BYTE (input, 5, NULL) == 'o' + && BYTE (input, 6, NULL) == 'r' + && BYTE (input, 7, NULL) == 't') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 6); + status = cr_token_set_import_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'm' + && BYTE (input, 3, NULL) == 'e' + && BYTE (input, 4, NULL) == 'd' + && BYTE (input, 5, NULL) == 'i' + && BYTE (input, 6, NULL) == 'a') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 5); + status = cr_token_set_media_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'p' + && BYTE (input, 3, NULL) == 'a' + && BYTE (input, 4, NULL) == 'g' + && BYTE (input, 5, NULL) == 'e') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 4); + status = cr_token_set_page_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + status = cr_tknzr_parse_atkeyword (a_this, &str); + if (status == CR_OK) { + status = cr_token_set_atkeyword (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break; + + case 'u': + + if (BYTE (input, 2, NULL) == 'r' + && BYTE (input, 3, NULL) == 'l' + && BYTE (input, 4, NULL) == '(') { + CRString *str2 = NULL; + + status = cr_tknzr_parse_uri (a_this, &str2); + if (status == CR_OK) { + status = cr_token_set_uri (token, str2); + CHECK_PARSING_STATUS (status, TRUE); + if (str2) { + cr_parsing_location_copy (&token->location, + &str2->location) ; + } + goto done; + } + } + goto fallback; + break; + + case 'r': + if (BYTE (input, 2, NULL) == 'g' + && BYTE (input, 3, NULL) == 'b' + && BYTE (input, 4, NULL) == '(') { + status = cr_tknzr_parse_rgb (a_this, &rgb); + if (status == CR_OK && rgb) { + status = cr_token_set_rgb (token, rgb); + CHECK_PARSING_STATUS (status, TRUE); + if (rgb) { + cr_parsing_location_copy (&token->location, + &rgb->location) ; + } + rgb = NULL; + goto done; + } + + } + goto fallback; + break; + + case '<': + if (BYTE (input, 2, NULL) == '!' + && BYTE (input, 3, NULL) == '-' + && BYTE (input, 4, NULL) == '-') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 3); + status = cr_token_set_cdo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '-': + if (BYTE (input, 2, NULL) == '-' + && BYTE (input, 3, NULL) == '>') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 2); + status = cr_token_set_cdc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } else { + status = cr_tknzr_parse_ident + (a_this, &str); + if (status == CR_OK) { + cr_token_set_ident + (token, str); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } else { + goto parse_number; + } + } + break; + + case '~': + if (BYTE (input, 2, NULL) == '=') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 1); + status = cr_token_set_includes (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '|': + if (BYTE (input, 2, NULL) == '=') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 1); + status = cr_token_set_dashmatch (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '/': + if (BYTE (input, 2, NULL) == '*') { + status = cr_tknzr_parse_comment (a_this, &str); + + if (status == CR_OK) { + status = cr_token_set_comment (token, str); + str = NULL; + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break ; + + case ';': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_semicolon (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '{': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_cbo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_tknzr_get_parsing_location (a_this, + &location) ; + goto done; + + case '}': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_cbc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '(': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_po (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ')': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_pc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '[': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_bo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ']': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_bc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + { + guchar *start = NULL, + *end = NULL; + + status = cr_tknzr_parse_w (a_this, &start, + &end, &location); + if (status == CR_OK) { + status = cr_token_set_s (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_tknzr_get_parsing_location (a_this, + &location) ; + goto done; + } + } + break; + + case '#': + { + status = cr_tknzr_parse_hash (a_this, &str); + if (status == CR_OK && str) { + status = cr_token_set_hash (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + goto done; + } + } + break; + + case '\'': + case '"': + status = cr_tknzr_parse_string (a_this, &str); + if (status == CR_OK && str) { + status = cr_token_set_string (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + goto done; + } + break; + + case '!': + status = cr_tknzr_parse_important (a_this, &location); + if (status == CR_OK) { + status = cr_token_set_important_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case '+': + /* '-' case is handled separately above for --> comments */ + parse_number: + { + CRNum *num = NULL; + + status = cr_tknzr_parse_num (a_this, &num); + if (status == CR_OK && num) { + next_bytes[0] = BYTE (input, 1, NULL); + next_bytes[1] = BYTE (input, 2, NULL); + next_bytes[2] = BYTE (input, 3, NULL); + next_bytes[3] = BYTE (input, 4, NULL); + + if (next_bytes[0] == 'e' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_EM; + status = cr_token_set_ems (token, + num); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'e' + && next_bytes[1] == 'x') { + num->type = NUM_LENGTH_EX; + status = cr_token_set_exs (token, + num); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 'x') { + num->type = NUM_LENGTH_PX; + status = cr_token_set_length + (token, num, LENGTH_PX_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'c' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_CM; + status = cr_token_set_length + (token, num, LENGTH_CM_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'm' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_MM; + status = cr_token_set_length + (token, num, LENGTH_MM_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'i' + && next_bytes[1] == 'n') { + num->type = NUM_LENGTH_IN; + status = cr_token_set_length + (token, num, LENGTH_IN_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 't') { + num->type = NUM_LENGTH_PT; + status = cr_token_set_length + (token, num, LENGTH_PT_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 'c') { + num->type = NUM_LENGTH_PC; + status = cr_token_set_length + (token, num, LENGTH_PC_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'd' + && next_bytes[1] == 'e' + && next_bytes[2] == 'g') { + num->type = NUM_ANGLE_DEG; + status = cr_token_set_angle + (token, num, ANGLE_DEG_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == 'r' + && next_bytes[1] == 'a' + && next_bytes[2] == 'd') { + num->type = NUM_ANGLE_RAD; + status = cr_token_set_angle + (token, num, ANGLE_RAD_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == 'g' + && next_bytes[1] == 'r' + && next_bytes[2] == 'a' + && next_bytes[3] == 'd') { + num->type = NUM_ANGLE_GRAD; + status = cr_token_set_angle + (token, num, ANGLE_GRAD_ET); + num = NULL; + SKIP_CHARS (a_this, 4); + } else if (next_bytes[0] == 'm' + && next_bytes[1] == 's') { + num->type = NUM_TIME_MS; + status = cr_token_set_time + (token, num, TIME_MS_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 's') { + num->type = NUM_TIME_S; + status = cr_token_set_time + (token, num, TIME_S_ET); + num = NULL; + SKIP_CHARS (a_this, 1); + } else if (next_bytes[0] == 'H' + && next_bytes[1] == 'z') { + num->type = NUM_FREQ_HZ; + status = cr_token_set_freq + (token, num, FREQ_HZ_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'k' + && next_bytes[1] == 'H' + && next_bytes[2] == 'z') { + num->type = NUM_FREQ_KHZ; + status = cr_token_set_freq + (token, num, FREQ_KHZ_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == '%') { + num->type = NUM_PERCENTAGE; + status = cr_token_set_percentage + (token, num); + num = NULL; + SKIP_CHARS (a_this, 1); + } else { + status = cr_tknzr_parse_ident (a_this, + &str); + if (status == CR_OK && str) { + num->type = NUM_UNKNOWN_TYPE; + status = cr_token_set_dimen + (token, num, str); + num = NULL; + CHECK_PARSING_STATUS (status, + TRUE); + str = NULL; + } else { + status = cr_token_set_number + (token, num); + num = NULL; + CHECK_PARSING_STATUS (status, CR_OK); + str = NULL; + } + } + if (token && token->u.num) { + cr_parsing_location_copy (&token->location, + &token->u.num->location) ; + } else { + status = CR_ERROR ; + } + goto done ; + } + } + break; + + default: + fallback: + /*process the fallback cases here */ + + if (next_char == '\\' + || (cr_utils_is_nonascii (next_char) == TRUE) + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z'))) { + status = cr_tknzr_parse_ident (a_this, &str); + if (status == CR_OK && str) { + guint32 next_c = 0; + + status = cr_input_peek_char + (PRIVATE (a_this)->input, &next_c); + + if (status == CR_OK && next_c == '(') { + + SKIP_CHARS (a_this, 1); + status = cr_token_set_function + (token, str); + CHECK_PARSING_STATUS (status, TRUE); + /*ownership is transferred + *to token by cr_token_set_function. + */ + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + } else { + status = cr_token_set_ident (token, + str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + } + goto done; + } else { + if (str) { + cr_string_destroy (str); + str = NULL; + } + } + } + break; + } + + READ_NEXT_CHAR (a_this, &next_char); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_delim (token, next_char); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + done: + + if (status == CR_OK && token) { + *a_tk = token; + /* + *store the previous position input stream pos. + */ + memmove (&PRIVATE (a_this)->prev_pos, + &init_pos, sizeof (CRInputPos)); + return CR_OK; + } + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (str) { + cr_string_destroy (str); + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; + +} + +enum CRStatus +cr_tknzr_parse_token (CRTknzr * a_this, enum CRTokenType a_type, + enum CRTokenExtraType a_et, gpointer a_res, + gpointer a_extra_res) +{ + enum CRStatus status = CR_OK; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_res, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_get_next_token (a_this, &token); + if (status != CR_OK) + return status; + if (token == NULL) + return CR_PARSING_ERROR; + + if (token->type == a_type) { + switch (a_type) { + case NO_TK: + case S_TK: + case CDO_TK: + case CDC_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case IMPORT_SYM_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + case IMPORTANT_SYM_TK: + status = CR_OK; + break; + + case STRING_TK: + case IDENT_TK: + case HASH_TK: + case ATKEYWORD_TK: + case FUNCTION_TK: + case COMMENT_TK: + case URI_TK: + *((CRString **) a_res) = token->u.str; + token->u.str = NULL; + status = CR_OK; + break; + + case EMS_TK: + case EXS_TK: + case PERCENTAGE_TK: + case NUMBER_TK: + *((CRNum **) a_res) = token->u.num; + token->u.num = NULL; + status = CR_OK; + break; + + case LENGTH_TK: + case ANGLE_TK: + case TIME_TK: + case FREQ_TK: + if (token->extra_type == a_et) { + *((CRNum **) a_res) = token->u.num; + token->u.num = NULL; + status = CR_OK; + } + break; + + case DIMEN_TK: + *((CRNum **) a_res) = token->u.num; + if (a_extra_res == NULL) { + status = CR_BAD_PARAM_ERROR; + goto error; + } + + *((CRString **) a_extra_res) = token->dimen; + token->u.num = NULL; + token->dimen = NULL; + status = CR_OK; + break; + + case DELIM_TK: + *((guint32 *) a_res) = token->u.unichar; + status = CR_OK; + break; + + case UNICODERANGE_TK: + default: + status = CR_PARSING_ERROR; + break; + } + + cr_token_destroy (token); + token = NULL; + } else { + cr_tknzr_unget_token (a_this, token); + token = NULL; + status = CR_PARSING_ERROR; + } + + return status; + + error: + + if (token) { + cr_tknzr_unget_token (a_this, token); + token = NULL; + } + + return status; +} + +void +cr_tknzr_destroy (CRTknzr * a_this) +{ + g_return_if_fail (a_this); + + if (PRIVATE (a_this) && PRIVATE (a_this)->input) { + if (cr_input_unref (PRIVATE (a_this)->input) + == TRUE) { + PRIVATE (a_this)->input = NULL; + } + } + + if (PRIVATE (a_this)->token_cache) { + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-tknzr.h b/src/3rdparty/libcroco/src/cr-tknzr.h new file mode 100644 index 0000000..13985b3 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-tknzr.h @@ -0,0 +1,115 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for coypyright information. + */ + +/** + *@file + *The declaration of the #CRTknzr (tokenizer) + *class. + */ + +#ifndef __CR_TKNZR_H__ +#define __CR_TKNZR_H__ + +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-token.h" + +G_BEGIN_DECLS + + +typedef struct _CRTknzr CRTknzr ; +typedef struct _CRTknzrPriv CRTknzrPriv ; + +/** + *The tokenizer is the class that knows + *about all the css token. Its main job is + *to return the next token found in the character + *input stream. + */ +struct _CRTknzr +{ + /*the private data of the tokenizer.*/ + CRTknzrPriv *priv ; +} ; + +CRTknzr * cr_tknzr_new (CRInput *a_input) ; + +CRTknzr * cr_tknzr_new_from_uri (const guchar *a_file_uri, + enum CREncoding a_enc) ; + +CRTknzr * cr_tknzr_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_at_destroy) ; + +gboolean cr_tknzr_unref (CRTknzr *a_this) ; + +void cr_tknzr_ref (CRTknzr *a_this) ; + +enum CRStatus cr_tknzr_read_byte (CRTknzr *a_this, guchar *a_byte) ; + +enum CRStatus cr_tknzr_read_char (CRTknzr *a_this, guint32 *a_char); + +enum CRStatus cr_tknzr_peek_char (CRTknzr *a_this, guint32 *a_char) ; + +enum CRStatus cr_tknzr_peek_byte (CRTknzr *a_this, gulong a_offset, + guchar *a_byte) ; + +guchar cr_tknzr_peek_byte2 (CRTknzr *a_this, gulong a_offset, + gboolean *a_eof) ; + +enum CRStatus cr_tknzr_set_cur_pos (CRTknzr *a_this, CRInputPos *a_pos) ; + +glong cr_tknzr_get_nb_bytes_left (CRTknzr *a_this) ; + +enum CRStatus cr_tknzr_get_cur_pos (CRTknzr *a_this, CRInputPos *a_pos) ; + +enum CRStatus cr_tknzr_get_parsing_location (CRTknzr *a_this, + CRParsingLocation *a_loc) ; + +enum CRStatus cr_tknzr_seek_index (CRTknzr *a_this, + enum CRSeekPos a_origin, + gint a_pos) ; + +enum CRStatus cr_tknzr_get_cur_byte_addr (CRTknzr *a_this, guchar **a_addr) ; + + +enum CRStatus cr_tknzr_consume_chars (CRTknzr *a_this, guint32 a_char, + glong *a_nb_char) ; + +enum CRStatus cr_tknzr_get_next_token (CRTknzr *a_this, CRToken ** a_tk) ; + +enum CRStatus cr_tknzr_unget_token (CRTknzr *a_this, CRToken *a_token) ; + + +enum CRStatus cr_tknzr_parse_token (CRTknzr *a_this, enum CRTokenType a_type, + enum CRTokenExtraType a_et, gpointer a_res, + gpointer a_extra_res) ; +enum CRStatus cr_tknzr_set_input (CRTknzr *a_this, CRInput *a_input) ; + +enum CRStatus cr_tknzr_get_input (CRTknzr *a_this, CRInput **a_input) ; + +void cr_tknzr_destroy (CRTknzr *a_this) ; + +G_END_DECLS + +#endif /*__CR_TKZNR_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-token.c b/src/3rdparty/libcroco/src/cr-token.c new file mode 100644 index 0000000..95226d7 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-token.c @@ -0,0 +1,636 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * see COPYRIGHTS file for copyright information. + */ + +/** + *@file + *The definition of the #CRToken class. + *Abstracts a css2 token. + */ +#include <string.h> +#include "cr-token.h" + +/* + *TODO: write a CRToken::to_string() method. + */ + +/** + *Frees the attributes of the current instance + *of #CRtoken. + *@param a_this the current instance of #CRToken. + */ +static void +cr_token_clear (CRToken * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case S_TK: + case CDO_TK: + case CDC_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + case IMPORT_SYM_TK: + case IMPORTANT_SYM_TK: + case SEMICOLON_TK: + case NO_TK: + case DELIM_TK: + case CBO_TK: + case CBC_TK: + case BO_TK: + case BC_TK: + break; + + case STRING_TK: + case IDENT_TK: + case HASH_TK: + case URI_TK: + case FUNCTION_TK: + case COMMENT_TK: + case ATKEYWORD_TK: + if (a_this->u.str) { + cr_string_destroy (a_this->u.str); + a_this->u.str = NULL; + } + break; + + case EMS_TK: + case EXS_TK: + case LENGTH_TK: + case ANGLE_TK: + case TIME_TK: + case FREQ_TK: + case PERCENTAGE_TK: + case NUMBER_TK: + case PO_TK: + case PC_TK: + if (a_this->u.num) { + cr_num_destroy (a_this->u.num); + a_this->u.num = NULL; + } + break; + + case DIMEN_TK: + if (a_this->u.num) { + cr_num_destroy (a_this->u.num); + a_this->u.num = NULL; + } + + if (a_this->dimen) { + cr_string_destroy (a_this->dimen); + a_this->dimen = NULL; + } + + break; + + case RGB_TK: + if (a_this->u.rgb) { + cr_rgb_destroy (a_this->u.rgb) ; + a_this->u.rgb = NULL ; + } + break ; + + case UNICODERANGE_TK: + /*not supported yet. */ + break; + + default: + cr_utils_trace_info ("I don't know how to clear this token\n") ; + break; + } + + a_this->type = NO_TK; +} + +/** + *Default constructor of + *the #CRToken class. + *@return the newly built instance of #CRToken. + */ +CRToken * +cr_token_new (void) +{ + CRToken *result = NULL; + + result = (CRToken *) g_try_malloc (sizeof (CRToken)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRToken)); + + return result; +} + +/** + *Sets the type of curren instance of + *#CRToken to 'S_TK' (S in the css2 spec) + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_s (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = S_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to 'CDO_TK' (CDO as said by the css2 spec) + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_cdo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CDO_TK; + + return CR_OK; +} + +/** + *Sets the type of the current token to + *CDC_TK (CDC as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_cdc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CDC_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to INCLUDES_TK (INCLUDES as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_includes (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = INCLUDES_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to DASHMATCH_TK (DASHMATCH as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_dashmatch (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = DASHMATCH_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_comment (CRToken * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = COMMENT_TK; + a_this->u.str = a_str ; + return CR_OK; +} + +enum CRStatus +cr_token_set_string (CRToken * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = STRING_TK; + + a_this->u.str = a_str ; + + return CR_OK; +} + +enum CRStatus +cr_token_set_ident (CRToken * a_this, CRString * a_ident) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = IDENT_TK; + a_this->u.str = a_ident; + return CR_OK; +} + + +enum CRStatus +cr_token_set_function (CRToken * a_this, CRString * a_fun_name) +{ + g_return_val_if_fail (a_this, + CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = FUNCTION_TK; + a_this->u.str = a_fun_name; + return CR_OK; +} + +enum CRStatus +cr_token_set_hash (CRToken * a_this, CRString * a_hash) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = HASH_TK; + a_this->u.str = a_hash; + + return CR_OK; +} + +enum CRStatus +cr_token_set_rgb (CRToken * a_this, CRRgb * a_rgb) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = RGB_TK; + a_this->u.rgb = a_rgb; + + return CR_OK; +} + +enum CRStatus +cr_token_set_import_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = IMPORT_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_page_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PAGE_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_media_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = MEDIA_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_font_face_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = FONT_FACE_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_charset_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = CHARSET_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_atkeyword (CRToken * a_this, CRString * a_atname) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = ATKEYWORD_TK; + a_this->u.str = a_atname; + return CR_OK; +} + +enum CRStatus +cr_token_set_important_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = IMPORTANT_SYM_TK; + return CR_OK; +} + +enum CRStatus +cr_token_set_ems (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = EMS_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_exs (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = EXS_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_length (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = LENGTH_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_angle (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = ANGLE_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_time (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = TIME_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_freq (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = FREQ_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_dimen (CRToken * a_this, CRNum * a_num, + CRString * a_dim) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = DIMEN_TK; + a_this->u.num = a_num; + a_this->dimen = a_dim; + return CR_OK; + +} + +enum CRStatus +cr_token_set_percentage (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PERCENTAGE_TK; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_number (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = NUMBER_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_uri (CRToken * a_this, CRString * a_uri) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = URI_TK; + a_this->u.str = a_uri; + + return CR_OK; +} + +enum CRStatus +cr_token_set_delim (CRToken * a_this, guint32 a_char) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = DELIM_TK; + a_this->u.unichar = a_char; + + return CR_OK; +} + +enum CRStatus +cr_token_set_semicolon (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = SEMICOLON_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_cbo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CBO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_cbc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CBC_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_po (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_pc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PC_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_bo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = BO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_bc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = BC_TK; + + return CR_OK; +} + +/** + *The destructor of the #CRToken class. + *@param a_this the current instance of #CRToken. + */ +void +cr_token_destroy (CRToken * a_this) +{ + g_return_if_fail (a_this); + + cr_token_clear (a_this); + + g_free (a_this); +} diff --git a/src/3rdparty/libcroco/src/cr-token.h b/src/3rdparty/libcroco/src/cr-token.h new file mode 100644 index 0000000..35e914d --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-token.h @@ -0,0 +1,212 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_TOKEN_H__ +#define __CR_TOKEN_H__ + +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-num.h" +#include "cr-rgb.h" +#include "cr-string.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +enum CRTokenType +{ + NO_TK, // 0 + S_TK, + CDO_TK, + CDC_TK, + INCLUDES_TK, + DASHMATCH_TK, // 5 + COMMENT_TK, + STRING_TK, + IDENT_TK, + HASH_TK, + IMPORT_SYM_TK, // 10 + PAGE_SYM_TK, + MEDIA_SYM_TK, + FONT_FACE_SYM_TK, + CHARSET_SYM_TK, + ATKEYWORD_TK, // 15 + IMPORTANT_SYM_TK, + EMS_TK, + EXS_TK, + LENGTH_TK, + ANGLE_TK, // 20 + TIME_TK, + FREQ_TK, + DIMEN_TK, + PERCENTAGE_TK, + NUMBER_TK, // 25 + RGB_TK, + URI_TK, + FUNCTION_TK, + UNICODERANGE_TK, + SEMICOLON_TK, // 30 + CBO_TK, /*opening curly bracket*/ + CBC_TK, /*closing curly bracket*/ + PO_TK, /*opening parenthesis*/ + PC_TK, /*closing parenthesis*/ + BO_TK, /*opening bracket*/ + BC_TK, /*closing bracket*/ + DELIM_TK +} ; + +enum CRTokenExtraType +{ + NO_ET = 0, + LENGTH_PX_ET, + LENGTH_CM_ET, + LENGTH_MM_ET, + LENGTH_IN_ET, + LENGTH_PT_ET, + LENGTH_PC_ET, + ANGLE_DEG_ET, + ANGLE_RAD_ET, + ANGLE_GRAD_ET, + TIME_MS_ET, + TIME_S_ET, + FREQ_HZ_ET, + FREQ_KHZ_ET +} ; + +typedef struct _CRToken CRToken ; + +/** + *This class abstracts a css2 token. + */ +struct _CRToken +{ + enum CRTokenType type ; + enum CRTokenExtraType extra_type ; + CRInputPos pos ; + + union + { + CRString *str ; + CRRgb *rgb ; + CRNum *num ; + guint32 unichar ; + } u ; + + CRString * dimen ; + CRParsingLocation location ; +} ; + +CRToken* cr_token_new (void) ; + +enum CRStatus cr_token_set_s (CRToken *a_this) ; + +enum CRStatus cr_token_set_cdo (CRToken *a_this) ; + +enum CRStatus cr_token_set_cdc (CRToken *a_this) ; + +enum CRStatus cr_token_set_includes (CRToken *a_this) ; + +enum CRStatus cr_token_set_dashmatch (CRToken *a_this) ; + +enum CRStatus cr_token_set_comment (CRToken *a_this, CRString *a_str) ; + +enum CRStatus cr_token_set_string (CRToken *a_this, CRString *a_str) ; + +enum CRStatus cr_token_set_ident (CRToken *a_this, CRString * a_ident) ; + +enum CRStatus cr_token_set_hash (CRToken *a_this, CRString *a_hash) ; + +enum CRStatus cr_token_set_rgb (CRToken *a_this, CRRgb *a_rgb) ; + +enum CRStatus cr_token_set_import_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_page_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_media_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_font_face_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_charset_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_atkeyword (CRToken *a_this, CRString *a_atname) ; + +enum CRStatus cr_token_set_important_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_ems (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_exs (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_length (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_angle (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_time (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_freq (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_dimen (CRToken *a_this, CRNum *a_num, + CRString *a_dim) ; + +enum CRStatus cr_token_set_percentage (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_number (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_uri (CRToken *a_this, CRString *a_uri) ; + +enum CRStatus cr_token_set_function (CRToken *a_this, + CRString *a_fun_name) ; + +enum CRStatus cr_token_set_bc (CRToken *a_this) ; + +enum CRStatus cr_token_set_bo (CRToken *a_this) ; + +enum CRStatus cr_token_set_po (CRToken *a_this) ; + +enum CRStatus cr_token_set_pc (CRToken *a_this) ; + +enum CRStatus cr_token_set_cbc (CRToken *a_this) ; + +enum CRStatus cr_token_set_cbo (CRToken *a_this) ; + +enum CRStatus cr_token_set_semicolon (CRToken *a_this) ; + +enum CRStatus cr_token_set_delim (CRToken *a_this, guint32 a_char) ; + + +/* + enum CRStatus + cr_token_set_unicoderange (CRToken *a_this, + CRUnicodeRange *a_range) ; +*/ + +void +cr_token_destroy (CRToken *a_this) ; + + +G_END_DECLS + +#endif /*__CR_TOKEN_H__*/ diff --git a/src/3rdparty/libcroco/src/cr-utils.c b/src/3rdparty/libcroco/src/cr-utils.c new file mode 100644 index 0000000..523362a --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-utils.c @@ -0,0 +1,1330 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "cr-utils.h" +#include "cr-string.h" + +/** + *@file: + *Some misc utility functions used + *in the libcroco. + *Note that troughout this file I will + *refer to the CSS SPECIFICATIONS DOCUMENTATION + *written by the w3c guys. You can find that document + *at http://www.w3.org/TR/REC-CSS2/ . + */ + +/**************************** + *Encoding transformations and + *encoding helpers + ****************************/ + +/* + *Here is the correspondence between the ucs-4 charactere codes + *and there matching utf-8 encoding pattern as dscribed by RFC 2279: + * + *UCS-4 range (hex.) UTF-8 octet sequence (binary) + *------------------ ----------------------------- + *0000 0000-0000 007F 0xxxxxxx + *0000 0080-0000 07FF 110xxxxx 10xxxxxx + *0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + *0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + *0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + *0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx + */ + +/** + *Given an utf8 string buffer, calculates + *the length of this string if it was encoded + *in ucs4. + *@param a_in_start a pointer to the beginning of + *the input utf8 string. + *@param a_in_end a pointre to the end of the input + *utf8 string (points to the last byte of the buffer) + *@param a_len out parameter the calculated length. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_utils_utf8_str_len_as_ucs4 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + guchar *byte_ptr = NULL; + gint len = 0; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + *a_len = 0; + + for (byte_ptr = (guchar *) a_in_start; + byte_ptr <= a_in_end; byte_ptr++) { + gint nb_bytes_2_decode = 0; + + if (*byte_ptr <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *byte_ptr; + nb_bytes_2_decode = 1; + + } else if ((*byte_ptr & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *byte_ptr & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*byte_ptr & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*byte_ptr & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*byte_ptr & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 3; + nb_bytes_2_decode = 5; + + } else if ((*byte_ptr & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 1; + nb_bytes_2_decode = 6; + + } else { + /* + *BAD ENCODING + */ + return CR_ENCODING_ERROR; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + byte_ptr++; + + /*byte pattern must be: 10xx xxxx */ + if ((*byte_ptr & 0xC0) != 0x80) { + return CR_ENCODING_ERROR; + } + + c = (c << 6) | (*byte_ptr & 0x3F); + } + + len++; + } + + *a_len = len; + + return CR_OK; +} + +/** + *Given an ucs4 string, this function + *returns the size (in bytes) this string + *would have occupied if it was encoded in utf-8. + *@param a_in_start a pointer to the beginning of the input + *buffer. + *@param a_in_end a pointer to the end of the input buffer. + *@param a_len out parameter. The computed length. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_str_len_as_utf8 (const guint32 * a_in_start, + const guint32 * a_in_end, gulong * a_len) +{ + gint len = 0; + guint32 *char_ptr = NULL; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + + for (char_ptr = (guint32 *) a_in_start; + char_ptr <= a_in_end; char_ptr++) { + if (*char_ptr <= 0x7F) { + /*the utf-8 char would take 1 byte */ + len += 1; + } else if (*char_ptr <= 0x7FF) { + /*the utf-8 char would take 2 bytes */ + len += 2; + } else if (*char_ptr <= 0xFFFF) { + len += 3; + } else if (*char_ptr <= 0x1FFFFF) { + len += 4; + } else if (*char_ptr <= 0x3FFFFFF) { + len += 5; + } else if (*char_ptr <= 0x7FFFFFFF) { + len += 6; + } + } + + *a_len = len; + return CR_OK; +} + +/** + *Given an ucsA string, this function + *returns the size (in bytes) this string + *would have occupied if it was encoded in utf-8. + *@param a_in_start a pointer to the beginning of the input + *buffer. + *@param a_in_end a pointer to the end of the input buffer. + *@param a_len out parameter. The computed length. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs1_str_len_as_utf8 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + gint len = 0; + guchar *char_ptr = NULL; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + + for (char_ptr = (guchar *) a_in_start; + char_ptr <= a_in_end; char_ptr++) { + if (*char_ptr <= 0x7F) { + /*the utf-8 char would take 1 byte */ + len += 1; + } else { + /*the utf-8 char would take 2 bytes */ + len += 2; + } + } + + *a_len = len; + return CR_OK; +} + +/** + *Converts an utf8 buffer into an ucs4 buffer. + * + *@param a_in the input utf8 buffer to convert. + *@param a_in_len in/out parameter. The size of the + *input buffer to convert. After return, this parameter contains + *the actual number of bytes consumed. + *@param a_out the output converted ucs4 buffer. Must be allocated by + *the caller. + *@param a_out_len in/out parameter. The size of the output buffer. + *If this size is actually smaller than the real needed size, the function + *just converts what it can and returns a success status. After return, + *this param points to the actual number of characters decoded. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong * a_in_len, guint32 * a_out, gulong * a_out_len) +{ + gulong in_len = 0, + out_len = 0, + in_index = 0, + out_index = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); + in_index++, out_index++) { + gint nb_bytes_2_decode = 0; + + if (a_in[in_index] <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = a_in[in_index]; + nb_bytes_2_decode = 1; + + } else if ((a_in[in_index] & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((a_in[in_index] & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((a_in[in_index] & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x7; + nb_bytes_2_decode = 4; + + } else if ((a_in[in_index] & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 3; + nb_bytes_2_decode = 5; + + } else if ((a_in[in_index] & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + in_index++; + + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + /************************ + *Some security tests + ***********************/ + + /*be sure c is a char */ + if (c == 0xFFFF || c == 0xFFFE) + goto end; + + /*be sure c is inferior to the max ucs4 char value */ + if (c > 0x10FFFF) + goto end; + + /* + *c must be less than UTF16 "lower surrogate begin" + *or higher than UTF16 "High surrogate end" + */ + if (c >= 0xD800 && c <= 0xDFFF) + goto end; + + /*Avoid characters that equals zero */ + if (c == 0) + goto end; + + a_out[out_index] = c; + } + + end: + *a_out_len = out_index + 1; + *a_in_len = in_index + 1; + + return status; +} + +/** + *Reads a character from an utf8 buffer. + *Actually decode the next character code (unicode character code) + *and returns it. + *@param a_in the starting address of the utf8 buffer. + *@param a_in_len the length of the utf8 buffer. + *@param a_out output parameter. The resulting read char. + *@param a_consumed the number of the bytes consumed to + *decode the returned character code. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_read_char_from_utf8_buf (const guchar * a_in, + gulong a_in_len, + guint32 * a_out, gulong * a_consumed) +{ + gulong in_index = 0, + nb_bytes_2_decode = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint32 c = 0; + + g_return_val_if_fail (a_in && a_out && a_out + && a_consumed, CR_BAD_PARAM_ERROR); + + if (a_in_len < 1) { + status = CR_OK; + goto end; + } + + if (*a_in <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *a_in; + nb_bytes_2_decode = 1; + + } else if ((*a_in & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *a_in & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*a_in & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*a_in & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*a_in & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *a_in & 3; + nb_bytes_2_decode = 5; + + } else if ((*a_in & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + goto end; + } + + if (nb_bytes_2_decode > a_in_len) { + status = CR_END_OF_INPUT_ERROR; + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (in_index = 1; in_index < nb_bytes_2_decode; in_index++) { + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + /************************ + *Some security tests + ***********************/ + + /*be sure c is a char */ + if (c == 0xFFFF || c == 0xFFFE) + goto end; + + /*be sure c is inferior to the max ucs4 char value */ + if (c > 0x10FFFF) + goto end; + + /* + *c must be less than UTF16 "lower surrogate begin" + *or higher than UTF16 "High surrogate end" + */ + if (c >= 0xD800 && c <= 0xDFFF) + goto end; + + /*Avoid characters that equals zero */ + if (c == 0) + goto end; + + *a_out = c; + + end: + *a_consumed = nb_bytes_2_decode; + + return status; +} + +/** + * + */ +enum CRStatus +cr_utils_utf8_str_len_as_ucs1 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + /* + *Note: this function can be made shorter + *but it considers all the cases of the utf8 encoding + *to ease further extensions ... + */ + + guchar *byte_ptr = NULL; + gint len = 0; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + *a_len = 0; + + for (byte_ptr = (guchar *) a_in_start; + byte_ptr <= a_in_end; byte_ptr++) { + gint nb_bytes_2_decode = 0; + + if (*byte_ptr <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *byte_ptr; + nb_bytes_2_decode = 1; + + } else if ((*byte_ptr & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *byte_ptr & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*byte_ptr & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*byte_ptr & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*byte_ptr & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 3; + nb_bytes_2_decode = 5; + + } else if ((*byte_ptr & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 1; + nb_bytes_2_decode = 6; + + } else { + /* + *BAD ENCODING + */ + return CR_ENCODING_ERROR; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + byte_ptr++; + + /*byte pattern must be: 10xx xxxx */ + if ((*byte_ptr & 0xC0) != 0x80) { + return CR_ENCODING_ERROR; + } + + c = (c << 6) | (*byte_ptr & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + if (c <= 0xFF) { /*Add other conditions to support + *other char sets (ucs2, ucs3, ucs4). + */ + len++; + } else { + /*the char is too long to fit + *into the supposed charset len. + */ + return CR_ENCODING_ERROR; + } + } + + *a_len = len; + + return CR_OK; +} + +/** + *Converts an utf8 string into an ucs4 string. + *@param a_in the input string to convert. + *@param a_in_len in/out parameter. The length of the input + *string. After return, points to the actual number of bytes + *consumed. This can be useful to debug the input stream in case + *of encoding error. + *@param a_out out parameter. Points to the output string. It is allocated + *by this function and must be freed by the caller. + *@param a_out_len out parameter. The length of the output string. + *@return CR_OK upon successful completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong * a_in_len, + guint32 ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + status = cr_utils_utf8_str_len_as_ucs4 (a_in, + &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + *a_out = (guint32 *) g_malloc0 (*a_out_len * sizeof (guint32)); + + status = cr_utils_utf8_to_ucs4 (a_in, a_in_len, *a_out, a_out_len); + + return status; +} + +/** + *Converts an ucs4 buffer into an utf8 buffer. + * + *@param a_in the input ucs4 buffer to convert. + *@param a_in_len in/out parameter. The size of the + *input buffer to convert. After return, this parameter contains + *the actual number of characters consumed. + *@param a_out the output converted utf8 buffer. Must be allocated by + *the caller. + *@param a_out_len in/out parameter. The size of the output buffer. + *If this size is actually smaller than the real needed size, the function + *just converts what it can and returns a success status. After return, + *this param points to the actual number of bytes in the buffer. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_to_utf8 (const guint32 * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong in_len = 0, + in_index = 0, + out_index = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out && a_out_len, + CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + + for (in_index = 0; in_index < in_len; in_index++) { + /* + *FIXME: return whenever we encounter forbidden char values. + */ + + if (a_in[in_index] <= 0x7F) { + a_out[out_index] = a_in[in_index]; + out_index++; + } else if (a_in[in_index] <= 0x7FF) { + a_out[out_index] = (0xC0 | (a_in[in_index] >> 6)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 2; + } else if (a_in[in_index] <= 0xFFFF) { + a_out[out_index] = (0xE0 | (a_in[in_index] >> 12)); + a_out[out_index + 1] = + (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 2] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 3; + } else if (a_in[in_index] <= 0x1FFFFF) { + a_out[out_index] = (0xF0 | (a_in[in_index] >> 18)); + a_out[out_index + 1] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 3] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 4; + } else if (a_in[in_index] <= 0x3FFFFFF) { + a_out[out_index] = (0xF8 | (a_in[in_index] >> 24)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] >> 18)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 3] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 4] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 5; + } else if (a_in[in_index] <= 0x7FFFFFFF) { + a_out[out_index] = (0xFC | (a_in[in_index] >> 30)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] >> 24)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 18) & 0x3F)); + a_out[out_index + 3] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 4] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 4] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 6; + } else { + status = CR_ENCODING_ERROR; + goto end; + } + } /*end for */ + + end: + *a_in_len = in_index + 1; + *a_out_len = out_index + 1; + + return status; +} + +/** + *Converts an ucs4 string into an utf8 string. + *@param a_in the input string to convert. + *@param a_in_len in/out parameter. The length of the input + *string. After return, points to the actual number of characters + *consumed. This can be useful to debug the input string in case + *of encoding error. + *@param a_out out parameter. Points to the output string. It is allocated + *by this function and must be freed by the caller. + *@param a_out_len out parameter. The length (in bytes) of the output string. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_str_to_utf8 (const guint32 * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out + && a_out_len, CR_BAD_PARAM_ERROR); + + status = cr_utils_ucs4_str_len_as_utf8 (a_in, + &a_in[*a_out_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + status = cr_utils_ucs4_to_utf8 (a_in, a_in_len, *a_out, a_out_len); + + return status; +} + +/** + *Converts an ucs1 buffer into an utf8 buffer. + *The caller must know the size of the resulting buffer and + *allocate it prior to calling this function. + * + *@param a_in the input ucs1 buffer. + * + *@param a_in_len in/out parameter. The length of the input buffer. + *After return, points to the number of bytes actually consumed even + *in case of encoding error. + * + *@param a_out out parameter. The output utf8 converted buffer. + * + *@param a_out_len in/out parameter. The size of the output buffer. + *If the output buffer size is shorter than the actual needed size, + *this function just convert what it can. + * + *@return CR_OK upon successful completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_ucs1_to_utf8 (const guchar * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong out_index = 0, + in_index = 0, + in_len = 0, + out_len = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out_len, + CR_BAD_PARAM_ERROR); + + if (*a_in_len == 0) { + *a_out_len = 0 ; + return status; + } + g_return_val_if_fail (a_out, CR_BAD_PARAM_ERROR) ; + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); in_index++) { + /* + *FIXME: return whenever we encounter forbidden char values. + */ + + if (a_in[in_index] <= 0x7F) { + a_out[out_index] = a_in[in_index]; + out_index++; + } else { + a_out[out_index] = (0xC0 | (a_in[in_index] >> 6)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 2; + } + } /*end for */ + + *a_in_len = in_index; + *a_out_len = out_index; + + return status; +} + +/** + *Converts an ucs1 string into an utf8 string. + *@param a_in_start the beginning of the input string to convert. + *@param a_in_end the end of the input string to convert. + *@param a_out out parameter. The converted string. + *@param a_out out parameter. The length of the converted string. + *@return CR_OK upon successful completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_ucs1_str_to_utf8 (const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + gulong out_len = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out + && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + *a_out_len = 0; + *a_out = NULL; + return CR_OK; + } + + status = cr_utils_ucs1_str_len_as_utf8 (a_in, &a_in[*a_in_len - 1], + &out_len); + + g_return_val_if_fail (status == CR_OK, status); + + *a_out = (guchar *) g_malloc0 (out_len); + + status = cr_utils_ucs1_to_utf8 (a_in, a_in_len, *a_out, &out_len); + + *a_out_len = out_len; + + return status; +} + +/** + *Converts an utf8 buffer into an ucs1 buffer. + *The caller must know the size of the resulting + *converted buffer, and allocated it prior to calling this + *function. + * + *@param a_in the input utf8 buffer to convert. + * + *@param a_in_len in/out parameter. The size of the input utf8 buffer. + *After return, points to the number of bytes consumed + *by the function even in case of encoding error. + * + *@param a_out out parameter. Points to the resulting buffer. + *Must be allocated by the caller. If the size of a_out is shorter + *than its required size, this function converts what it can and return + *a successful status. + * + *@param a_out_len in/out parameter. The size of the output buffer. + *After return, points to the number of bytes consumed even in case of + *encoding error. + * + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_utils_utf8_to_ucs1 (const guchar * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong in_index = 0, + out_index = 0, + in_len = 0, + out_len = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint32 c = 0; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + goto end; + } + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); + in_index++, out_index++) { + gint nb_bytes_2_decode = 0; + + if (a_in[in_index] <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = a_in[in_index]; + nb_bytes_2_decode = 1; + + } else if ((a_in[in_index] & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((a_in[in_index] & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((a_in[in_index] & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x7; + nb_bytes_2_decode = 4; + + } else if ((a_in[in_index] & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 3; + nb_bytes_2_decode = 5; + + } else if ((a_in[in_index] & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + status = CR_ENCODING_ERROR; + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + if (in_index + nb_bytes_2_decode - 1 >= in_len) { + goto end; + } + + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + in_index++; + + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + status = CR_ENCODING_ERROR; + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + if (c > 0xFF) { + status = CR_ENCODING_ERROR; + goto end; + } + + a_out[out_index] = c; + } + + end: + *a_out_len = out_index; + *a_in_len = in_index; + + return status; +} + +/** + *Converts an utf8 buffer into an + *ucs1 buffer. + *@param a_in_start the start of the input buffer. + *@param a_in_end the end of the input buffer. + *@param a_out out parameter. The resulting converted ucs4 buffer. + *Must be freed by the caller. + *@param a_out_len out parameter. The length of the converted buffer. + *@return CR_OK upon successful completion, an error code otherwise. + *Note that out parameters are valid if and only if this function + *returns CR_OK. + */ +enum CRStatus +cr_utils_utf8_str_to_ucs1 (const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + *a_out_len = 0; + *a_out = NULL; + return CR_OK; + } + + status = cr_utils_utf8_str_len_as_ucs4 (a_in, &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + *a_out = (guchar *) g_malloc0 (*a_out_len * sizeof (guint32)); + + status = cr_utils_utf8_to_ucs1 (a_in, a_in_len, *a_out, a_out_len); + return status; +} + +/***************************************** + *CSS basic types identification utilities + *****************************************/ + +/** + *Returns TRUE if a_char is a white space as + *defined in the css spec in chap 4.1.1. + * + *white-space ::= ' '| \t|\r|\n|\f + * + *@param a_char the character to test. + *return TRUE if is a white space, false otherwise. + */ +gboolean +cr_utils_is_white_space (guint32 a_char) +{ + switch (a_char) { + case ' ': + case '\t': + case '\r': + case '\n': + case '\f': + return TRUE; + break; + default: + return FALSE; + } +} + +/** + *Returns true if the character is a newline + *as defined in the css spec in the chap 4.1.1. + * + *nl ::= \n|\r\n|\r|\f + * + *@param a_char the character to test. + *@return TRUE if the character is a newline, FALSE otherwise. + */ +gboolean +cr_utils_is_newline (guint32 a_char) +{ + switch (a_char) { + case '\n': + case '\r': + case '\f': + return TRUE; + break; + default: + return FALSE; + } +} + +/** + *returns TRUE if the char is part of an hexa num char: + *i.e hexa_char ::= [0-9A-F] + */ +gboolean +cr_utils_is_hexa_char (guint32 a_char) +{ + if ((a_char >= '0' && a_char <= '9') + || (a_char >= 'A' && a_char <= 'F')) { + return TRUE; + } + return FALSE; +} + +/** + *Returns true if the character is a nonascii + *character (as defined in the css spec chap 4.1.1): + * + *nonascii ::= [^\0-\177] + * + *@param a_char the character to test. + *@return TRUE if the character is a nonascii char, + *FALSE otherwise. + */ +gboolean +cr_utils_is_nonascii (guint32 a_char) +{ + if (a_char <= 177) { + return FALSE; + } + + return TRUE; +} + +/** + *Dumps a character a_nb times on a file. + *@param a_char the char to dump + *@param a_fp the destination file pointer + *@param a_nb the number of times a_char is to be dumped. + */ +void +cr_utils_dump_n_chars (guchar a_char, FILE * a_fp, glong a_nb) +{ + glong i = 0; + + for (i = 0; i < a_nb; i++) { + fprintf (a_fp, "%c", a_char); + } +} + +void +cr_utils_dump_n_chars2 (guchar a_char, GString * a_string, glong a_nb) +{ + glong i = 0; + + g_return_if_fail (a_string); + + for (i = 0; i < a_nb; i++) { + g_string_append_printf (a_string, "%c", a_char); + } +} + +/** + *Duplicates a list of GString instances. + *@return the duplicated list of GString instances or NULL if + *something bad happened. + *@param a_list_of_strings the list of strings to be duplicated. + */ +GList * +cr_utils_dup_glist_of_string (GList const * a_list_of_strings) +{ + GList const *cur = NULL; + GList *result = NULL; + + g_return_val_if_fail (a_list_of_strings, NULL); + + for (cur = a_list_of_strings; cur; cur = cur->next) { + GString *str = NULL; + + str = g_string_new_len (((GString *) cur->data)->str, + ((GString *) cur->data)->len); + if (str) + result = g_list_append (result, str); + } + + return result; +} + +/** + *Duplicate a GList where the GList::data is a CRString. + *@param a_list_of_strings the list to duplicate + *@return the duplicated list, or NULL if something bad + *happened. + */ +GList * +cr_utils_dup_glist_of_cr_string (GList const * a_list_of_strings) +{ + GList const *cur = NULL; + GList *result = NULL; + + g_return_val_if_fail (a_list_of_strings, NULL); + + for (cur = a_list_of_strings; cur; cur = cur->next) { + CRString *str = NULL; + + str = cr_string_dup ((CRString const *) cur->data) ; + if (str) + result = g_list_append (result, str); + } + + return result; +} diff --git a/src/3rdparty/libcroco/src/cr-utils.h b/src/3rdparty/libcroco/src/cr-utils.h new file mode 100644 index 0000000..cff9c80 --- /dev/null +++ b/src/3rdparty/libcroco/src/cr-utils.h @@ -0,0 +1,245 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * Look at file COPYRIGHTS for copyright information + */ + +#ifndef __CR_DEFS_H__ +#define __CR_DEFS_H__ + +#include <stdio.h> +#include <glib.h> + +G_BEGIN_DECLS + +/** + *@file + *The Croco library basic types definitions + *And global definitions. + */ + +/** + *The status type returned + *by the methods of the croco library. + */ +enum CRStatus { + CR_OK, + CR_BAD_PARAM_ERROR, + CR_INSTANCIATION_FAILED_ERROR, + CR_UNKNOWN_TYPE_ERROR, + CR_UNKNOWN_PROP_ERROR, + CR_UNKNOWN_PROP_VAL_ERROR, + CR_UNEXPECTED_POSITION_SCHEME, + CR_START_OF_INPUT_ERROR, + CR_END_OF_INPUT_ERROR, + CR_OUTPUT_TOO_SHORT_ERROR, + CR_INPUT_TOO_SHORT_ERROR, + CR_OUT_OF_BOUNDS_ERROR, + CR_EMPTY_PARSER_INPUT_ERROR, + CR_ENCODING_ERROR, + CR_ENCODING_NOT_FOUND_ERROR, + CR_PARSING_ERROR, + CR_SYNTAX_ERROR, + CR_NO_ROOT_NODE_ERROR, + CR_NO_TOKEN, + CR_OUT_OF_MEMORY_ERROR, + CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR, + CR_BAD_PSEUDO_CLASS_SEL_HANDLER_ERROR, + CR_ERROR, + CR_FILE_NOT_FOUND_ERROR, + CR_VALUE_NOT_FOUND_ERROR +} ; + +/** + *Values used by + *cr_input_seek_position() ; + */ +enum CRSeekPos { + CR_SEEK_CUR, + CR_SEEK_BEGIN, + CR_SEEK_END +} ; + +/** + *Encoding values. + */ +enum CREncoding +{ + CR_UCS_4 = 1/*Must be not NULL*/, + CR_UCS_1, + CR_ISO_8859_1, + CR_ASCII, + CR_UTF_8, + CR_UTF_16, + CR_AUTO/*should be the last one*/ +} ; + + + + +#define CROCO_LOG_DOMAIN "LIBCROCO" + +#ifdef __GNUC__ +#define cr_utils_trace(a_log_level, a_msg) \ +g_log (CROCO_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): %s\n", \ + __FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__, \ + a_msg) +#else /*__GNUC__*/ + +#define cr_utils_trace(a_log_level, a_msg) \ +g_log (CROCO_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d: %s\n", \ + __FILE__, \ + __LINE__, \ + a_msg) +#endif + +/** + *Traces an info message. + *The file, line and enclosing function + *of the message will be automatically + *added to the message. + *@param a_msg the msg to trace. + */ +#define cr_utils_trace_info(a_msg) \ +cr_utils_trace (G_LOG_LEVEL_INFO, a_msg) + +/** + *Trace a debug message. + *The file, line and enclosing function + *of the message will be automatically + *added to the message. + *@param a_msg the msg to trace. + */ +#define cr_utils_trace_debug(a_msg) \ +cr_utils_trace (G_LOG_LEVEL_DEBUG, a_msg) ; + + +/**************************** + *Encoding transformations and + *encoding helpers + ****************************/ + +enum CRStatus +cr_utils_read_char_from_utf8_buf (const guchar * a_in, gulong a_in_len, + guint32 *a_out, gulong *a_consumed) ; + +enum CRStatus +cr_utils_ucs1_to_utf8 (const guchar *a_in, gulong *a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_to_ucs1 (const guchar * a_in, gulong * a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_ucs4_to_utf8 (const guint32 *a_in, gulong *a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_str_len_as_ucs4 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_ucs1_str_len_as_utf8 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_utf8_str_len_as_ucs1 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_ucs4_str_len_as_utf8 (const guint32 *a_in_start, + const guint32 *a_in_end, + gulong *a_len) ; + +enum CRStatus +cr_utils_ucs1_str_to_utf8 (const guchar *a_in_start, + gulong *a_in_len, + guchar **a_out, + gulong *a_len) ; + +enum CRStatus +cr_utils_utf8_str_to_ucs1 (const guchar * a_in_start, + gulong * a_in_len, + guchar **a_out, + gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong * a_in_len, + guint32 *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_ucs4_str_to_utf8 (const guint32 *a_in, + gulong *a_in_len, + guchar **a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong *a_in_len, + guint32 **a_out, + gulong *a_out_len) ; + + +/***************************************** + *CSS basic types identification utilities + *****************************************/ + +gboolean +cr_utils_is_newline (guint32 a_char) ; + +gboolean +cr_utils_is_white_space (guint32 a_char) ; + +gboolean +cr_utils_is_nonascii (guint32 a_char) ; + +gboolean +cr_utils_is_hexa_char (guint32 a_char) ; + + +/********************************** + *Miscellaneous utility functions + ***********************************/ + +void +cr_utils_dump_n_chars (guchar a_char, + FILE *a_fp, + glong a_nb) ; + +void +cr_utils_dump_n_chars2 (guchar a_char, + GString *a_string, + glong a_nb) ; +GList * +cr_utils_dup_glist_of_string (GList const *a_list) ; + +GList * +cr_utils_dup_glist_of_cr_string (GList const * a_list_of_strings) ; + +G_END_DECLS + +#endif /*__CR_DEFS_H__*/ diff --git a/src/3rdparty/libcroco/src/libcroco-config.h.in b/src/3rdparty/libcroco/src/libcroco-config.h.in new file mode 100644 index 0000000..7f2e217 --- /dev/null +++ b/src/3rdparty/libcroco/src/libcroco-config.h.in @@ -0,0 +1,17 @@ +#ifndef LIBCROCO_VERSION_NUMBER +#define LIBCROCO_VERSION_NUMBER @LIBCROCO_VERSION_NUMBER@ +#endif + +#ifndef LIBCROCO_VERSION +#define LIBCROCO_VERSION "@LIBCROCO_VERSION@" +#endif + +#ifndef G_DISABLE_CHECKS +#if @G_DISABLE_CHECKS@ +#define G_DISABLE_CHECKS @G_DISABLE_CHECKS@ +#endif +#endif + +#ifndef CROCO_HAVE_LIBXML2 +#define CROCO_HAVE_LIBXML2 (1) +#endif diff --git a/src/3rdparty/libcroco/src/libcroco.h b/src/3rdparty/libcroco/src/libcroco.h new file mode 100644 index 0000000..eabc596 --- /dev/null +++ b/src/3rdparty/libcroco/src/libcroco.h @@ -0,0 +1,44 @@ +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef __LIBCROCO_H__ +#define __LIBCROCO_H__ + +#include "libcroco-config.h" + +#include "cr-utils.h" +#include "cr-pseudo.h" +#include "cr-term.h" +#include "cr-attr-sel.h" +#include "cr-simple-sel.h" +#include "cr-selector.h" +#include "cr-enc-handler.h" +#include "cr-doc-handler.h" +#include "cr-input.h" +#include "cr-parser.h" +#include "cr-statement.h" +#include "cr-stylesheet.h" +#include "cr-om-parser.h" +#include "cr-prop-list.h" +#include "cr-sel-eng.h" +#include "cr-style.h" +#include "cr-string.h" + +#endif /*__LIBCROCO_H__*/ diff --git a/src/3rdparty/libcroco/src/libcroco.symbols b/src/3rdparty/libcroco/src/libcroco.symbols new file mode 100644 index 0000000..c201652 --- /dev/null +++ b/src/3rdparty/libcroco/src/libcroco.symbols @@ -0,0 +1,538 @@ +;This file is part of The Croco Library +;This program is free software; you can redistribute it and/or +;modify it under the terms of version 2.1 of the GNU Lesser General Public +;License as published by the Free Software Foundation. + +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;GNU General Public License for more details. + +;You should have received a copy of the GNU Lesser General Public License +;along with this program; if not, write to the Free Software +;Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +;USA + +;Author: Fan, Chun-wei +;See COPYRIGHTS file for copyright information. + +;---------------------------- +;libcroco/cr-additional-sel.h +;---------------------------- +cr_additional_sel_append +cr_additional_sel_destroy +cr_additional_sel_dump +cr_additional_sel_new +cr_additional_sel_new_with_type +cr_additional_sel_one_to_string +cr_additional_sel_prepend +cr_additional_sel_set_attr_sel +cr_additional_sel_set_class_name +cr_additional_sel_set_id_name +cr_additional_sel_set_pseudo +cr_additional_sel_to_string + +;---------------------- +;libcroco/cr-attr-sel.h +;---------------------- +cr_attr_sel_append_attr_sel +cr_attr_sel_destroy +cr_attr_sel_dump +cr_attr_sel_new +cr_attr_sel_prepend_attr_sel +cr_attr_sel_to_string + +;--------------------- +;libcroco/cr-cascade.h +;--------------------- +cr_cascade_destroy +cr_cascade_get_sheet +cr_cascade_new +cr_cascade_ref +cr_cascade_set_sheet +cr_cascade_unref + +;------------------------- +;libcroco/cr-declaration.h +;------------------------- +cr_declaration_append +cr_declaration_append2 +cr_declaration_destroy +cr_declaration_dump +cr_declaration_dump_one +cr_declaration_get_by_prop_name +cr_declaration_get_from_list +cr_declaration_list_to_string +cr_declaration_list_to_string2 +cr_declaration_new +cr_declaration_nr_props +cr_declaration_parse_from_buf +cr_declaration_parse_list_from_buf +cr_declaration_prepend +cr_declaration_ref +cr_declaration_to_string +cr_declaration_unlink +cr_declaration_unref + +;------------------------- +;libcroco/cr-doc-handler.h +;------------------------- +cr_doc_handler_associate_a_parser +cr_doc_handler_destroy +cr_doc_handler_get_ctxt +cr_doc_handler_get_result +cr_doc_handler_new +cr_doc_handler_ref +cr_doc_handler_set_ctxt +cr_doc_handler_set_default_sac_handler +cr_doc_handler_set_result +cr_doc_handler_unref + +;------------------------- +;libcroco/cr-enc-handler.h +;------------------------- +cr_enc_handler_convert_input +cr_enc_handler_get_instance +cr_enc_handler_resolve_enc_alias + +;------------------- +;libcroco/cr-fonts.h +;------------------- +cr_font_family_append +cr_font_family_destroy +cr_font_family_new +cr_font_family_prepend +cr_font_family_set_name +cr_font_family_to_string +cr_font_size_adjust_destroy +cr_font_size_adjust_new +cr_font_size_adjust_to_string +cr_font_size_clear +cr_font_size_copy +cr_font_size_destroy +cr_font_size_get_larger_predefined_font_size +cr_font_size_get_smaller_predefined_font_size +cr_font_size_is_predefined_absolute_font_size +cr_font_size_is_set_to_inherit +cr_font_size_new +cr_font_size_set_absolute_font_size +cr_font_size_set_predefined_absolute_font_size +cr_font_size_set_relative_font_size +cr_font_size_set_to_inherit +cr_font_size_to_string +cr_font_stretch_to_string +cr_font_style_to_string +cr_font_variant_to_string +cr_font_weight_get_bolder +cr_font_weight_to_string + +;------------------- +;libcroco/cr-input.h +;------------------- +cr_input_consume_char +cr_input_consume_chars +cr_input_consume_white_spaces +cr_input_destroy +cr_input_end_of_input +cr_input_get_byte_addr +cr_input_get_column_num +cr_input_get_cur_pos +cr_input_get_cur_byte_addr +cr_input_get_cur_index +cr_input_get_end_of_file +cr_input_get_end_of_line +cr_input_get_line_num +cr_input_get_nb_bytes_left +cr_input_get_parsing_location +cr_input_increment_col_num +cr_input_increment_line_num +cr_input_new_from_buf +cr_input_new_from_uri +cr_input_peek_byte +cr_input_peek_byte2 +cr_input_peek_char +cr_input_read_byte +cr_input_read_char +cr_input_ref +cr_input_seek_index +cr_input_set_column_num +cr_input_set_cur_index +cr_input_set_cur_pos +cr_input_set_end_of_file +cr_input_set_end_of_line +cr_input_set_line_num +cr_input_unref + +;----------------- +;libcroco/cr-num.h +;----------------- +cr_num_copy +cr_num_destroy +cr_num_dup +cr_num_is_fixed_length +cr_num_new +cr_num_new_with_val +cr_num_set +cr_num_to_string + +;----------------------- +;libcroco/cr-om-parser.h +;----------------------- +cr_om_parser_destroy +cr_om_parser_new +cr_om_parser_parse_buf +cr_om_parser_parse_file +cr_om_parser_parse_paths_to_cascade +cr_om_parser_simply_parse_buf +cr_om_parser_simply_parse_file +cr_om_parser_simply_parse_paths_to_cascade + +;-------------------- +;libcroco/cr-parser.h +;-------------------- +cr_parser_destroy +cr_parser_get_sac_handler +cr_parser_get_tknzr +cr_parser_get_use_core_grammar +cr_parser_get_parsing_location +cr_parser_new +cr_parser_new_from_buf +cr_parser_new_from_file +cr_parser_new_from_input +cr_parser_parse +cr_parser_parse_buf +cr_parser_parse_charset +cr_parser_parse_declaration +cr_parser_parse_expr +cr_parser_parse_file +cr_parser_parse_font_face +cr_parser_parse_import +cr_parser_parse_media +cr_parser_parse_page +cr_parser_parse_prio +cr_parser_parse_ruleset +cr_parser_parse_statement_core +cr_parser_parse_term +cr_parser_set_default_sac_handler +cr_parser_set_sac_handler +cr_parser_set_use_core_grammar +cr_parser_set_tknzr +cr_parser_try_to_skip_spaces_and_comments + +;------------------------------ +;libcroco/cr-parsing-location.h +;------------------------------ +cr_parsing_location_copy +cr_parsing_location_destroy +cr_parsing_location_dump +cr_parsing_location_init +cr_parsing_location_new +cr_parsing_location_to_string + +;----------------------- +;libcroco/cr-prop-list.h +;----------------------- +cr_prop_list_append +cr_prop_list_append2 +cr_prop_list_destroy +cr_prop_list_get_decl +cr_prop_list_get_next +cr_prop_list_get_prev +cr_prop_list_get_prop +cr_prop_list_lookup_prop +cr_prop_list_prepend +cr_prop_list_prepend2 +cr_prop_list_set_decl +cr_prop_list_set_prop +cr_prop_list_unlink + +;-------------------- +;libcroco/cr-pseudo.h +;-------------------- +cr_pseudo_destroy +cr_pseudo_dump +cr_pseudo_new +cr_pseudo_to_string + +;----------------- +;libcroco/cr-rgb.h +;----------------- +cr_rgb_compute_from_percentage +cr_rgb_copy +cr_rgb_destroy +cr_rgb_dump +cr_rgb_is_set_to_inherit +cr_rgb_is_set_to_transparent +cr_rgb_new +cr_rgb_new_with_vals +cr_rgb_parse_from_buf +cr_rgb_set +cr_rgb_set_from_hex_str +cr_rgb_set_from_name +cr_rgb_set_from_rgb +cr_rgb_set_from_term +cr_rgb_set_to_inherit +cr_rgb_set_to_transparent +cr_rgb_to_string + +;---------------------- +;libcroco/cr-selector.h +;---------------------- +cr_selector_append +cr_selector_append_simple_sel +cr_selector_destroy +cr_selector_dump +cr_selector_new +cr_selector_parse_from_buf +cr_selector_prepend +cr_selector_ref +cr_selector_to_string +cr_selector_unref + +;--------------------- +;libcroco/cr-sel-eng.h +;--------------------- +cr_sel_eng_destroy +cr_sel_eng_get_matched_properties_from_cascade +cr_sel_eng_get_matched_rulesets +cr_sel_eng_get_matched_style +cr_sel_eng_get_pseudo_class_selector_handler +cr_sel_eng_matches_node +cr_sel_eng_new +cr_sel_eng_register_pseudo_class_sel_handler +cr_sel_eng_unregister_all_pseudo_class_sel_handlers +cr_sel_eng_unregister_pseudo_class_sel_handler + +;------------------------ +;libcroco/cr-simple-sel.h +;------------------------ +cr_simple_sel_append_simple_sel +cr_simple_sel_compute_specificity +cr_simple_sel_destroy +cr_simple_sel_dump +;cr_simple_sel_dump_attr_sel_list ;no implementation! +cr_simple_sel_new +cr_simple_sel_one_to_string +cr_simple_sel_prepend_simple_sel +cr_simple_sel_to_string + +;----------------------- +;libcroco/cr-statement.h +;----------------------- +cr_statement_append +cr_statement_at_charset_rule_get_charset +cr_statement_at_charset_rule_parse_from_buf +cr_statement_at_charset_rule_set_charset +cr_statement_at_font_face_rule_add_decl +cr_statement_at_font_face_rule_get_decls +cr_statement_at_font_face_rule_set_decls +cr_statement_at_import_rule_get_imported_sheet +cr_statement_at_import_rule_get_url +cr_statement_at_import_rule_parse_from_buf +cr_statement_at_import_rule_set_imported_sheet +cr_statement_at_import_rule_set_url +cr_statement_at_media_get_from_list +cr_statement_at_media_nr_rules +cr_statement_at_media_rule_parse_from_buf +cr_statement_at_page_rule_get_declarations +;cr_statement_at_page_rule_get_sel ;no implementation! +cr_statement_at_page_rule_parse_from_buf +cr_statement_at_page_rule_set_declarations +;cr_statement_at_page_rule_set_sel ;no implementation! +cr_statement_destroy +cr_statement_does_buf_parses_against_core +cr_statement_dump +cr_statement_dump_charset +cr_statement_dump_font_face_rule +cr_statement_dump_import_rule +cr_statement_dump_media_rule +cr_statement_dump_page +cr_statement_dump_ruleset +cr_statement_font_face_rule_parse_from_buf +cr_statement_get_from_list +cr_statement_get_parent_sheet +cr_statement_list_to_string +cr_statement_new_at_charset_rule +cr_statement_new_at_font_face_rule +cr_statement_new_at_import_rule +cr_statement_new_at_media_rule +cr_statement_new_at_page_rule +cr_statement_new_ruleset +cr_statement_nr_rules +cr_statement_parse_from_buf +cr_statement_prepend +cr_statement_ruleset_append_decl +cr_statement_ruleset_append_decl2 +cr_statement_ruleset_get_declarations +cr_statement_ruleset_set_decl_list +cr_statement_ruleset_get_sel_list +cr_statement_ruleset_parse_from_buf +cr_statement_ruleset_set_sel_list +cr_statement_set_parent_sheet +cr_statement_to_string +cr_statement_unlink + +;-------------------- +;libcroco/cr-string.h +;-------------------- +cr_string_destroy +cr_string_dup +cr_string_dup2 +cr_string_new +cr_string_new_from_gstring +cr_string_new_from_string +cr_string_peek_raw_str +cr_string_peek_raw_str_len + +;------------------------ +;libcroco/cr-stylesheet.h +;------------------------ +cr_stylesheet_destroy +cr_stylesheet_dump +cr_stylesheet_new +cr_stylesheet_nr_rules +cr_stylesheet_ref +cr_stylesheet_statement_get_from_list +cr_stylesheet_to_string +cr_stylesheet_unref + +;------------------- +;libcroco/cr-style.h +;------------------- +cr_style_border_style_to_string +cr_style_copy +cr_style_destroy +cr_style_display_type_to_string +cr_style_dup +cr_style_float_type_to_string +cr_style_new +cr_style_num_prop_val_to_string +cr_style_position_type_to_string +;cr_style_propagate_from_parent ;no implementation! +cr_style_ref +cr_style_resolve_inherited_properties +cr_style_rgb_prop_val_to_string +cr_style_set_props_to_default_values +cr_style_set_props_to_initial_values +cr_style_set_style_from_decl +cr_style_to_string +cr_style_unref +cr_style_white_space_type_to_string + +;------------------ +;libcroco/cr-term.h +;------------------ +cr_term_append_term +cr_term_destroy +cr_term_dump +cr_term_get_from_list +cr_term_new +cr_term_nr_values +cr_term_one_to_string +cr_term_parse_expression_from_buf +cr_term_prepend_term +cr_term_ref +cr_term_set_function +cr_term_set_hash +cr_term_set_ident +cr_term_set_number +cr_term_set_rgb +cr_term_set_string +cr_term_set_uri +cr_term_to_string +cr_term_unref + +;------------------- +;libcroco/cr-tknzr.h +;------------------- +cr_tknzr_consume_chars +cr_tknzr_destroy +cr_tknzr_get_cur_byte_addr +cr_tknzr_get_cur_pos +cr_tknzr_get_input +cr_tknzr_get_nb_bytes_left +cr_tknzr_get_next_token +cr_tknzr_get_parsing_location +cr_tknzr_new +cr_tknzr_new_from_buf +cr_tknzr_new_from_uri +cr_tknzr_parse_token +cr_tknzr_peek_byte +cr_tknzr_peek_byte2 +cr_tknzr_peek_char +cr_tknzr_read_byte +cr_tknzr_read_char +cr_tknzr_ref +cr_tknzr_seek_index +cr_tknzr_set_cur_pos +cr_tknzr_set_input +cr_tknzr_unget_token +cr_tknzr_unref + +;------------------- +;libcroco/cr-token.h +;------------------- +cr_token_destroy +cr_token_new +cr_token_set_angle +cr_token_set_atkeyword +cr_token_set_bc +cr_token_set_bo +cr_token_set_cbc +cr_token_set_cbo +cr_token_set_cdc +cr_token_set_cdo +cr_token_set_charset_sym +cr_token_set_comment +cr_token_set_dashmatch +cr_token_set_delim +cr_token_set_dimen +cr_token_set_ems +cr_token_set_exs +cr_token_set_font_face_sym +cr_token_set_freq +cr_token_set_function +cr_token_set_hash +cr_token_set_important_sym +cr_token_set_import_sym +cr_token_set_includes +cr_token_set_ident +cr_token_set_length +cr_token_set_media_sym +cr_token_set_number +cr_token_set_page_sym +cr_token_set_pc +cr_token_set_percentage +cr_token_set_po +cr_token_set_rgb +cr_token_set_s +cr_token_set_semicolon +cr_token_set_string +cr_token_set_time +;cr_token_set_unicoderange ;commented out in the header! +cr_token_set_uri + +;------------------- +;libcroco/cr-utils.h +;------------------- +cr_utils_dump_n_chars +cr_utils_dump_n_chars2 +cr_utils_dup_glist_of_cr_string +cr_utils_dup_glist_of_string +cr_utils_is_hexa_char +cr_utils_is_newline +cr_utils_is_nonascii +cr_utils_is_white_space +cr_utils_read_char_from_utf8_buf +cr_utils_ucs1_str_len_as_utf8 +cr_utils_ucs1_str_to_utf8 +cr_utils_ucs1_to_utf8 +cr_utils_ucs4_str_len_as_utf8 +cr_utils_ucs4_str_to_utf8 +cr_utils_ucs4_to_utf8 +cr_utils_utf8_str_len_as_ucs4 +cr_utils_utf8_to_ucs1 +cr_utils_utf8_to_ucs4 +cr_utils_utf8_str_len_as_ucs1 +cr_utils_utf8_str_to_ucs1 +cr_utils_utf8_str_to_ucs4
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/CMakeLists.txt b/src/3rdparty/libcroco/tests/CMakeLists.txt new file mode 100644 index 0000000..1ffb908 --- /dev/null +++ b/src/3rdparty/libcroco/tests/CMakeLists.txt @@ -0,0 +1,69 @@ +set(testprogs + test0 + test1 + test2 + test3 + test4 + test5 + test6 + test7 + test8 +) + +foreach(source ${testprogs}) + add_executable(${source} ${source}-main.c cr-test-utils.c cr-test-utils.h) + + target_include_directories(${source} + PRIVATE + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src + ${GLIB_INCLUDE_DIRS} + ${LIBXML_INCLUDE_DIRS} + ) + + target_link_libraries(${source} + croco_LIB + ) +endforeach() + +if(1) + # Run each test separately + + set(testscripts + test-functional-notation.sh + test-lots-of-comments.sh + test-parsing-location.sh + test-prop-ident.sh + test-sel-child-class.sh + test-several-media.sh + test-unknown-at-rule2.sh + test-unknown-at-rule.sh + ) + + add_test(NAME cleantest + COMMAND ${CMAKE_SOURCE_DIR}/tests/testctl cleanup + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + + foreach(source ${testprogs} ${testscripts}) + add_test(NAME ${source} + COMMAND ${CMAKE_SOURCE_DIR}/tests/testctl run --test-and-report ${source} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + set_tests_properties(${source} PROPERTIES DEPENDS "cleantest") + endforeach() +else() + # Run all tests at once + add_test(NAME all-tests + COMMAND ${CMAKE_SOURCE_DIR}/tests/testctl run + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) +endif() + +get_property(test_names DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY TESTS) +set_property(TEST ${test_names} PROPERTY ENVIRONMENT + "TEST_OUT_DIR=${CMAKE_CURRENT_BINARY_DIR}" + "TEST_SOURCE_DIR=${CMAKE_SOURCE_DIR}/tests" + "TEST_INPUTS_DIR=${CMAKE_SOURCE_DIR}/tests/test-inputs" + "CSSLINT=${CMAKE_BINARY_DIR}/csslint/csslint" +) diff --git a/src/3rdparty/libcroco/tests/Makefile.am b/src/3rdparty/libcroco/tests/Makefile.am new file mode 100644 index 0000000..666eff8 --- /dev/null +++ b/src/3rdparty/libcroco/tests/Makefile.am @@ -0,0 +1,36 @@ +SUBDIRS = test-inputs test-output-refs +EXTRA_DIST = testctl vg.supp global-vars.sh.in valgrind-version.sh \ +test-prop-ident.sh test-unknown-at-rule.sh test-unknown-at-rule2.sh \ +test-several-media.sh + + +#the list of all possible tests goes here. + +EXTRALDFLAGS = $(CROCO_LIBS) +testprogs=test0 test1 test2 test3 test4 test5 test6 test7 test8 +noinst_PROGRAMS = $(testprogs) +test0_SOURCES = test0-main.c +test0_LDFLAGS = $(EXTRALDFLAGS) +test1_SOURCES = test1-main.c +test1_LDFLAGS = $(EXTRALDFLAGS) +test2_SOURCES = test2-main.c cr-test-utils.c cr-test-utils.h +test2_LDFLAGS = $(EXTRALDFLAGS) +test3_SOURCES = test3-main.c cr-test-utils.c cr-test-utils.h +test3_LDFLAGS = $(EXTRALDFLAGS) +test4_SOURCES = test4-main.c cr-test-utils.c cr-test-utils.h +test4_LDFLAGS = $(EXTRALDFLAGS) +test5_SOURCES = test5-main.c cr-test-utils.c cr-test-utils.h +test5_LDFLAGS = $(EXTRALDFLAGS) +test6_SOURCES = test6-main.c cr-test-utils.c cr-test-utils.h +test6_LDFLAGS = $(EXTRALDFLAGS) +test7_SOURCES = test7-main.c cr-test-utils.c cr-test-utils.h +test7_LDFLAGS = $(EXTRALDFLAGS) +test8_SOURCES = test8-main.c +test8_LDFLAGS = $(EXTRALDFLAGS) + +croco_lib = $(top_builddir)/src/@CROCO_LIB@ +LDADD = $(croco_lib) + +AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/src -I$(top_builddir)/src + +AM_CFLAGS = -I. $(CROCO_CFLAGS) diff --git a/src/3rdparty/libcroco/tests/README-description.txt b/src/3rdparty/libcroco/tests/README-description.txt new file mode 100644 index 0000000..a81336f --- /dev/null +++ b/src/3rdparty/libcroco/tests/README-description.txt @@ -0,0 +1,125 @@ +This file describes the tests present in the libcroro tests directory. +===================================================================== + +Initial author: Dodji Seketeli <dodji@seketeli.org> + +Each entry of this file is orgnised as follows: + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: name-of-the-test-binary-file + +source-file: name-of-the-test-source-file + +purpose: purpose of the test. + +description: description of the test +""""""""""""""""""""""""""""""""""""""""""""""""" + +And, in the words of RMS, happy hacking ! + + Dodji +################################################################## + + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test0 + +source-file: test0-main.c + +purpose: Tests the cr_input_read_byte() method of the CRInput class. + +description: opens the file located at the path in parameter and +loads it into an input stream using the cr_input_new_from_uri() +method of the CRInput class. +Then, reads the bytes from the input stream using the cr_input_read_byte() +method and dumps each byte read to stdout. +Note that the input file must be encoded in utf8. + +""""""""""""""""""""""""""""""""""""""""""""""""" + + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test1 + +source-file: test1-main.c + +purpose: Test the read_char() method of the CRInput class. + +description: opens the file located at the path in parameter and +loads it into an input stream using the cr_input_new_from_uri() +method of the CRInput class. +Then, reads characters from the input stream using the cr_input_read_char() +method and dumps each character on stdout. +Note that the input file must be encoded in utf8. +""""""""""""""""""""""""""""""""""""""""""""""""" + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test2 + +source-file: test2-main.c + +purpose: tests the sac api of the parser. + +description: it loads the file located at the path given +in argument, instantiates a sac parser, set document +handlers and parses the file. +The doc handlers simply dump the name name of the callback +which is being called and some basic additional information. +""""""""""""""""""""""""""""""""""""""""""""""""" + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test3 + +source-file: test3-main.c + +purpose: Test the SAC api core css grammar parsing + +description: it loads the file located at the path given +in argument, instantiates a sac parser, set document +handlers and parses the file using the css2 core syntax. +The doc handlers simply dump the name name of the callback +which is being called and some basic additional information. +Here, the goal is that nothing is dump on screen because +during the parsing using the core grammar syntax, no callback +should be called. +""""""""""""""""""""""""""""""""""""""""""""""""" + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test4 + +source-file: test4-main.c + +purpose: tests the cssom parser interface (cr-om-parser.c) + +description: parses the file located at the path given in +parameter and dumps the result of the parsing (the object model) +on stdout. +""""""""""""""""""""""""""""""""""""""""""""""""" + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test5 + +source-file: test5-main.c + +purpose: tests the selector cr-sel-eng.c basic functionalities. + +description: parses an in memory xml document hardwired in the +test5-main.c file; parses the stylesheet given in parameter to +the test5 binary. +Walks down the xml document tree and runs the selector engine +on each xml document node to get the css rule that matches it. +Displays a report that basically say: "this xml node was matched +by this set of css rules" +""""""""""""""""""""""""""""""""""""""""""""""""" + +""""""""""""""""""""""""""""""""""""""""""""""""" +binary: test6 + +source-file: test6-main.c + +purpose: tests the "in memory" css2 parsing capabilities. (cr_om_parser_parse_buf) + + +description: parses an "in memory" hardwired css2 stylesheet +and dumps it on stdout. +"""""""""""""""""""""""""""""""""""""""""""""""""
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/cr-test-utils.c b/src/3rdparty/libcroco/tests/cr-test-utils.c new file mode 100644 index 0000000..9435ef7 --- /dev/null +++ b/src/3rdparty/libcroco/tests/cr-test-utils.c @@ -0,0 +1,59 @@ +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <string.h> +#include "cr-test-utils.h" + +/** + *Parses the command line. + *@param a_argc the argc parameter of the main routine. + *@param the argv parameter of the main routine. + *@param a_options out parameter the parsed options. + */ +void +cr_test_utils_parse_cmd_line (int a_argc, char **a_argv, + struct Options *a_options) +{ + int i = 0; + + g_return_if_fail (a_options); + + memset (a_options, 0, sizeof (struct Options)); + + for (i = 1; i < a_argc; i++) { + if (a_argv[i][0] != '-') + break; + + if (!strcmp (a_argv[i], "-h") + || !strcmp (a_argv[i], "--help")) { + a_options->display_help = TRUE; + } + if (!strcmp (a_argv[i], "--about")) { + a_options->display_about = TRUE; + } + } + + if (i >= a_argc) { + /*No file parameter where given */ + a_options->files_list = NULL; + } else { + a_options->files_list = &a_argv[i]; + } +} diff --git a/src/3rdparty/libcroco/tests/cr-test-utils.h b/src/3rdparty/libcroco/tests/cr-test-utils.h new file mode 100644 index 0000000..9219b93 --- /dev/null +++ b/src/3rdparty/libcroco/tests/cr-test-utils.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ +#ifndef __CR_TEST_UTILS_H__ +#define __CR_TEST_UTILS_H__ + +#include <stdio.h> +#include <glib.h> + +/** + *The options data structure. + *The variable of this data structure are set + *during the parsing the command line by the + *parse_command_line() function. + */ +struct Options +{ + gboolean display_help ; + gboolean display_about ; + gchar ** files_list ; +}; + + +void +cr_test_utils_parse_cmd_line (int a_argc, char **a_argv, + struct Options *a_options) ; + +#endif /*__CR_TEST_UTILS_H__*/ diff --git a/src/3rdparty/libcroco/tests/global-vars.sh.in b/src/3rdparty/libcroco/tests/global-vars.sh.in new file mode 100644 index 0000000..e291459 --- /dev/null +++ b/src/3rdparty/libcroco/tests/global-vars.sh.in @@ -0,0 +1,10 @@ +TEST_INPUTS_DIR=$HERE_DIR/test-inputs +CSSLINT=$HERE_DIR/../csslint/.libs/csslint-@LIBCROCO_MAJOR_VERSION@.@LIBCROCO_MINOR_VERSION@ +if ! test -x $CSSLINT ; then + echo "Aarg Could not find an executable csslint. I was looking for $CSSLINT" + echo $ +fi + +if ! test x"$VALGRIND" = x ; then + CSSLINT="$VALGRIND $CSSLINT" +fi diff --git a/src/3rdparty/libcroco/tests/test-functional-notation.sh b/src/3rdparty/libcroco/tests/test-functional-notation.sh new file mode 100755 index 0000000..2860092 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-functional-notation.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT $TEST_INPUTS_DIR/functional-notation.css diff --git a/src/3rdparty/libcroco/tests/test-inputs/Makefile.am b/src/3rdparty/libcroco/tests/test-inputs/Makefile.am new file mode 100644 index 0000000..3c93d8f --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/Makefile.am @@ -0,0 +1,16 @@ +EXTRA_DIST= prop-vendor-ident.css \ +test0.1.css \ +test1.css \ +test2.1.css \ +test2.2.css \ +test2.css \ +test3.1.css \ +test3.2.css \ +test3.css \ +test4.1.css \ +test4.2.css \ +test5.1.css \ +unknown-at-rule2.css \ +unknown-at-rule.css \ +several-media.css + diff --git a/src/3rdparty/libcroco/tests/test-inputs/functional-notation.css b/src/3rdparty/libcroco/tests/test-inputs/functional-notation.css new file mode 100644 index 0000000..cd80f18 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/functional-notation.css @@ -0,0 +1,2 @@ +foo { bar: attr(width, length, calc(70% - 5px)) } +foo {bar: attr(x,y) } diff --git a/src/3rdparty/libcroco/tests/test-inputs/lots-of-comments.css b/src/3rdparty/libcroco/tests/test-inputs/lots-of-comments.css new file mode 100644 index 0000000..87a6e4a --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/lots-of-comments.css @@ -0,0 +1,198 @@ + + +@charset "utf8"; + +/******************************************** + * Parsing location information of the @charset rule + ********************************************/ + /*@charset*/ + /*line:1 column:1 byte offset:0 */ + /*utf8*/ + /*line:1 column:10 byte offset:9 */ + +@import url("http://pouet.com") screen, paper, aural; + +/***************************************************** + *Parsing location information for the @import rule + ******************************************************/ + + /*@import*/ + /*line:3 column:1 byte offset:19 */ + + /*http://pouet.com*/ + /*line:3 column:13 byte offset:31 */ + + /*screen*/ + /*line:3 column:33 byte offset:51 */ + + /*paper*/ + /*line:3 column:41 byte offset:59 */ + + /*aural*/ + /*line:3 column:48 byte offset:66 */ + +@page coin :pseudo-page + + /*@page*/ + /*line:5 column:1 byte offset:75 */ + /*coin*/ + /*line:5 column:7 byte offset:81 */ + /*pseudo-page*/ + /*line:5 column:13 byte offset:87 */ + +{ + + +page-prop0 : page-val0; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*page-prop0*/ + /*line:6 column:7 byte offset:107 */ + /*page-val0*/ + /*line:6 column:19 byte offset:119 */ + + +page-prop1 : page-val1; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*page-prop1*/ + /*line:7 column:7 byte offset:137 */ + /*page-val1*/ + /*line:7 column:19 byte offset:149 */ +} +@media paper, aural + /*@media*/ + /*line:10 column:1 byte offset:164 */ + /*paper*/ + /*line:10 column:8 byte offset:171 */ + /*aural*/ + /*line:10 column:15 byte offset:178 */ + +{ +x { +/************************************************ + *Parsing location information of the selector + ************************************************/ +/*x*/ +/*line:11 column:5 byte offset:190 */ + /*x*/ + /*line:11 column:5 byte offset:190 */ + + +foo : fooval; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*foo*/ + /*line:12 column:7 byte offset:200 */ + /*fooval*/ + /*line:12 column:12 byte offset:205 */ + + +bar : barval; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*bar*/ + /*line:13 column:7 byte offset:220 */ + /*barval*/ + /*line:13 column:12 byte offset:225 */ + } + +} +@font-face { +/****************************************************** + Parsing location information for the @font-face rule + ******************************************************/ + + /*@font-face*/ + /*line:17 column:1 byte offset:243 */ + + +font-prop1 : font1; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*font-prop1*/ + /*line:18 column:2 byte offset:257 */ + /*font1*/ + /*line:18 column:14 byte offset:269 */ + + +font-prop2 : font2; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*font-prop2*/ + /*line:19 column:2 byte offset:278 */ + /*font2*/ + /*line:19 column:14 byte offset:290 */ +} +x>y[attr="val"].class#tatati z+toto { +/************************************************ + *Parsing location information of the selector + ************************************************/ +/*x*/ +/*line:21 column:1 byte offset:300 */ + /*x*/ + /*line:21 column:1 byte offset:300 */ +/*y[attr="val"].class#tatati*/ +/*line:21 column:5 byte offset:304 */ + /*y*/ + /*line:21 column:5 byte offset:304 */ + + /*[attr="val"]*/ + /*line:21 column:6 byte offset:305 */ + + /*.class*/ + /*line:21 column:17 byte offset:316 */ + + /*#tatati*/ + /*line:21 column:22 byte offset:321 */ +/*z*/ +/*line:21 column:30 byte offset:329 */ + /*z*/ + /*line:21 column:30 byte offset:329 */ +/*toto*/ +/*line:21 column:34 byte offset:333 */ + /*toto*/ + /*line:21 column:34 byte offset:333 */ + + +prop1 : function(a); + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*prop1*/ + /*line:22 column:2 byte offset:340 */ + /*function(a)*/ + /*line:22 column:9 byte offset:347 */ + + +prop2 : val2; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*prop2*/ + /*line:23 column:2 byte offset:362 */ + /*val2*/ + /*line:23 column:9 byte offset:369 */ + } diff --git a/src/3rdparty/libcroco/tests/test-inputs/parsing-location.css b/src/3rdparty/libcroco/tests/test-inputs/parsing-location.css new file mode 100644 index 0000000..f760b07 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/parsing-location.css @@ -0,0 +1,26 @@ +@charset "utf8" ; + +@import url("http://pouet.com") screen, paper, aural ; +@import url(http://pouet.com) screen2, paper2, aural2 ; + +@page coin :pseudo-page { + page-prop0: page-val0 ; + page-prop1: page-val1 ; +} + +@media paper, aural { + x { + foo: fooval ; + bar: barval ; + } +} + +@font-face { + font-prop1: font1 ; + font-prop2: font2 ; +} +x > y[attr=val].class#tatati z + toto{ + prop1: function(a) ; + prop2: val2 +} + diff --git a/src/3rdparty/libcroco/tests/test-inputs/prop-vendor-ident.css b/src/3rdparty/libcroco/tests/test-inputs/prop-vendor-ident.css new file mode 100644 index 0000000..f7aa8b5 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/prop-vendor-ident.css @@ -0,0 +1,3 @@ +:-foo-pseudo { + -foo-bar-prop: -foobar-value +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.css b/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.css new file mode 100644 index 0000000..a6ea36b --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.css @@ -0,0 +1 @@ +body > div p.process { color: aqua; } diff --git a/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.xml b/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.xml new file mode 100644 index 0000000..ee5e23d --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/sel-child-class.xml @@ -0,0 +1,10 @@ +<test> + <body> + <div> + <div> + <p class="process">This should be aqua</p> + </div> + </div> + </body> +</test> + diff --git a/src/3rdparty/libcroco/tests/test-inputs/several-media.css b/src/3rdparty/libcroco/tests/test-inputs/several-media.css new file mode 100644 index 0000000..79dc336 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/several-media.css @@ -0,0 +1,10 @@ +@media screen { +a:link { text-decoration: none; } +div { width: 50%; } +} + +@media print { +a { color: red; } +div { width: 57%; } +} + diff --git a/src/3rdparty/libcroco/tests/test-inputs/test0.1.css b/src/3rdparty/libcroco/tests/test-inputs/test0.1.css new file mode 100644 index 0000000..f8e842e --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test0.1.css @@ -0,0 +1,258 @@ +body { + margin : 0px 0px 20px 0px; + height : 100%; + background : #FFF +} + +A { + color : #003366; + text-decoration : underline +} + +A:link { + color : #003366; + text-decoration : underline +} + +A:visited { + color : #003366; + text-decoration : underline +} + +A:active { + color : #999999 +} + +A:hover { + color : #999999 +} + +h1, h2, h3 { + margin : 0px; + padding : 0px +} + +#banner { + font-family : palatino, georgia, verdana, arial, sans-serif; + color : #333; + top:0; + font-size : normal; + font-weight : normal; +} + +#banner a, #banner a:link, #banner a:visited, #banner a:active, #banner a:hover { + font-family : verdana, arial, sans-serif; + font-size : xx-large; + color : #333; + text-decoration : none +} + +.description { + font-family : verdana, arial, sans-serif; + color : #333; + font-size : small; + text-transform : none +} + +#content { + position : absolute; + background : #FFF; + top: 20%; + left: 20%; + border : 1px solid #FFF +} + +#container { + background : #FFF; + border : 1px solid #FFF +} + +#links { + padding : 15px; + border : 1px solid #FFF; + width : 200px +} + +.blog { + padding : 20px; + background : #FFF +} + +.blogbody { + font-family : verdana, arial, sans-serif; + color : #333; + font-size : small; + font-weight : normal; + background : #FFF; + line-height : 150% +} + +.blogbody a, .blogbody a:link, .blogbody a:visited, .blogbody a:active, .blogbody a:hover { + font-weight : normal; + text-decoration : underline +} + +.title { + font-family : verdana, arial, sans-serif; + font-size : medium; + color : #666 +} + +.date { + font-family : verdana, arial, serif; + font-size : large; + color : #333; + border-bottom : 1px solid #999; + margin-bottom : 10px; + font-weight : bold +} + +.posted { + font-family : verdana, arial, sans-serif; + font-size : x-small; + color : #000000; + margin-bottom : 25px +} + +.calendar { + font-family : verdana, arial, sans-serif; + color : #333; + font-size : x-small; + font-weight : normal; + background : #FFF; + line-height : 140%; + padding : 2px; + text-align : left +} + +.calendarhead { + font-family : palatino, georgia, times new roman, serif; + color : #666600; + font-size : small; + font-weight : normal; + padding : 2px; + letter-spacing : 0.3em; + background : #FFF; + text-transform : uppercase; + text-align : left +} + +.side { + font-family : verdana, arial, sans-serif; + color : #333; + font-size : x-small; + font-weight : normal; + background : #FFF; + line-height : 140%; + padding : 2px +} + +#menubar { + font-family : verdana, arial, sans-serif; + color : #333; + font-size : small; + font-weight : normal; + position:absolute; + top:20%; + padding: 2px; + letter-spacing : 0.1em; + background : #FFF; + text-transform : uppercase +} + +.syndicate { + font-family : verdana, arial, sans-serif; + font-size : xx-small; + line-height : 140%; + padding : 2px; + margin-top : 15px; + background : #FFF +} + +.powered { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : x-small; + line-height : 140%; + text-transform : uppercase; + padding : 2px; + margin-top : 50px; + letter-spacing : 0.2em; + background : #FFF +} + +.comments-body { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : small; + font-weight : normal; + background : #FFF; + line-height : 140%; + padding-bottom : 10px; + padding-top : 10px; + border-bottom : 1px dotted #999 +} + +.comments-post { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : x-small; + font-weight : normal; + background : #FFF +} + +.trackback-url { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : small; + font-weight : normal; + background : #FFF; + line-height : 140%; + padding : 5px; + border : 1px dotted #999 +} + +.trackback-body { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : small; + font-weight : normal; + background : #FFF; + line-height : 140%; + padding-bottom : 10px; + padding-top : 10px; + border-bottom : 1px dotted #999 +} + +.trackback-post { + font-family : verdana, arial, sans-serif; + color : #666; + font-size : x-small; + font-weight : normal; + background : #FFF +} + +.comments-head { + font-family : verdana, arial, sans-serif; + font-size : small; + color : #666; + border-bottom : 1px solid #999; + margin-top : 20px; + font-weight : bold; + background : #FFF +} + +#banner-commentspop { + font-family : verdana, arial, sans-serif; + color : #FFF; + font-size : large; + font-weight : bold; + border-left : 1px solid #FFF; + border-right : 1px solid #FFF; + border-top : 1px solid #FFF; + background : #003366; + padding-left : 15px; + padding-right : 15px; + padding-top : 5px; + padding-bottom : 5px +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test1.css b/src/3rdparty/libcroco/tests/test-inputs/test1.css new file mode 100644 index 0000000..b03c8a4 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test1.css @@ -0,0 +1,316 @@ +body { + + background-color: #E5E5E5; + + scrollbar-face-color: #CCCCCC; + + scrollbar-highlight-color: #FFFFFF; + + scrollbar-shadow-color: #CCCCCC; + + scrollbar-3dlight-color: #D1D7DC; + + scrollbar-arrow-color: #000000; + + scrollbar-track-color: #FFFFFF; + + scrollbar-darkshadow-color: #000000; + +} + + + +font, th, td, p { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + +} + + + +h1, h2 { font-size: 11px; color: #000000; font-weight: bold; } + + + +a:link, a:active, a:visited { color: #000000; } + + + +a:hover { color: #CC0000; text-decoration: underline; } + + + +hr { height: 0px; border: solid #CCCCCC 0px; border-top-width: 1px; } + + + +small { font-size: 10px; } + + + +input, textarea, select { + + font: normal 11px Verdana, Arial, Helvetica, sans-serif; + + color: #000000; + + border-color: #000000; + +} + + + +input { text-indent: 2px; } + + + + +input.post, textarea.post, select { + + background-color: #FFFFFF; + +} + + + + +th { + + font-size: 11px; color: #CCCCCC; font-weight: bold; + + background-color: #000000; height: 25px; + + background-image: url(/~wiceyto/test/templates/blacknwhite/images/cellpic3.gif); + +} + + + + +.fontspec, .tablefont { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + +} + + + +.navbartext, .navbarfont { + + font-size: 11px; color: #000000; font-weight: bold; + +} + + + +.navbartext a, .navbarfont a { + + color: #000000; font-weight: bold; text-decoration: none; + +} + + + +.navbartext a:hover, .navbarfont a:hover { + + color: #CC0000; text-decoration: none; + +} + + + +.tablespec, .guestbook { background-color: #FFFFFF; border: 2px #000000 solid; } + +.tablespec th, .tablespec td { color: #000000; background-color: #CCCCCC; } + +.tablespec th { background-image: none; } + + + +.messageblock { + + border: dashed 1px; + + margin-right: 4em; margin-left: 4em; + + padding: 3em; + +} + + + +/* $MessageOpenCode - the body of text of the posts */ + +.messagebody { font-size: 12px; line-height: 18px; } + +.messagebody a { color: #000000; text-decoration: underline; } + +.messagebody a:hover { color: #CC0000; text-decoration: underline; } + + + + +.newcode { font-size: 11px; color: #CC0000; font-weight: bold; } + +.admincode { font-size: 11px; color: #990000; font-style: bold; } + + + + +.bodyline { background-color: #FFFFFF; border: 1px #000000 solid; } + + + + +.quote, .code { + + background-color: #FAFAFA; border: #D1D7DC; border-style: solid; + + border-top-width: 1px; border-right-width: 1px; + + border-bottom-width: 1px; border-left-width: 1px; + +} + + + +.quote { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + + color: #444444; line-height: 125%; + +} + + + +.code { + + font-family: Courier, 'Courier New', sans-serif; + + font-size: 11px; + + color: #CC0000; + +} + + + + +input.button { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + + color: #000000; + + background-color: #FFFFFF; + +} + + + +/* Format button rollover help line. Actually it's a text box + + set to the same color as the background so no one will know. */ + +.helpline { background-color: #CCCCCC; border-style: none; } + + + +/* additional table cell colors and backgrounds */ + +td.row2 { background-color: #CCCCCC; } + +td.row1 { background-color: #CCCCCC; } + +td.row3 { background-color: #D1D7DC; } + + + +/* additional general text */ + +.gen { font-size: 12px; } + +.genmed { font-size: 11px; } + +.gensmall { font-size: 10px; } + +.gen, .genmed, .gensmall { color: #000000; } + +a.gen, a.genmed, a.gensmall { color: #000000; text-decoration: none; } + +a.gen:hover, a.genmed:hover, a.gensmall:hover { color: #CC0000; text-decoration: underline; } + + + +/* import fancy styles. For IE only. NS4.x doesn't use the @import function */ + +@import url("/your.site/webbbs/themes/formIE.css"); + + + +/* END of blacknwhite.css */ + + + + + + + +/* Appendix.2-2: Example fancy styles CSS file + +Paste these into a text file and save as formIE.css */ + + + +/* Fancy form styles for IE */ + + + +input, textarea, select { + +border-top-width : 1px; + +border-right-width : 1px; + +border-bottom-width : 1px; + +border-left-width : 1px; + +} + + + +input { text-indent : 2px; } + + + +input.button { + +border-top-width : 1px; + +border-right-width : 1px; + +border-bottom-width : 1px; + +border-left-width : 1px; + +} + + + +.postbody { line-height: 18px} + +.magic { + margin-left: -20px; +} + +/* END of formIE.css */ diff --git a/src/3rdparty/libcroco/tests/test-inputs/test2.1.css b/src/3rdparty/libcroco/tests/test-inputs/test2.1.css new file mode 100644 index 0000000..ba447fb --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test2.1.css @@ -0,0 +1,47 @@ + +/*simple Attribute set selectors*/ +s1[foo] {prop1 : "\53 tring"} + +/* line break is invalid */ +s2[foo] {prop1 : " +tring"} + +/*simple exact attribute selector, simple ruleset*/ +s3[foo="warning"] {prop1 : value1} + +/** + *"space separated value list" + *attribute selector, simple ruleset + */ +s4[foo~="warning"] {prop1 :value1} + +/** + *"hyphen separated value list" attribute selector, + * simple ruleset + */ + + /*simple class selector, simple ruleset*/ + s5.warning {prop1 : value} + + E#myid {prop1 : value1} + + +/*below are tests that we know are working*/ + +/*simple ident pseudo class selector, simple ruleset test*/ +S6:first-child {prop1 : value1 ; prop2 : value2} + +/*function pseudo class selector, simple ruleset test*/ +S7:lang(c) {prop1 : value1} + +/*Adjacent selectors, simple ruleset test*/ +S8 + s2 {prop1: value1} + +/* quoted strings */ +.quotedstrings { + -test-string1: "foo'bar"; + -test-string2: 'foo\'bar'; + -test-string3: 'foo"bar'; + -test-string4: "foo\"bar"; + -test-string5: 'foo\\bar'; +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test2.2.css b/src/3rdparty/libcroco/tests/test-inputs/test2.2.css new file mode 100644 index 0000000..0a58bbe --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test2.2.css @@ -0,0 +1,686 @@ +p.commentsbody { + border-left-style: solid; + border-width: 1px; + border-color: rgb(0, 0, 0); + padding-left: 10px; + margin-right: 20px; + text-align: justify; +} + +* { + font-family: Verdana, Arial, Helvetica, sans-serif, monospace; +} + +body { + background: #606060; + color: #000000; +} + +a:link { + color: #0000FF; + background: transparent; + text-decoration: none; +} + +a:visited { + color: #990099; + background: transparent; + text-decoration: none; +} + + +a:active { + color: #000000; + background: #ADD8E6; + text-decoration: none; +} + + +h1.rubrique_info { + color: #990033; + margin: 0px 0px 0px 0px; + padding: 0em; + border: 0px; + font-size: 12px; +} + + +h1.connexe { + font-size: 12px; + padding: 0em; + margin: 0px 0px 0px 0px; + color: #990033; +} + +a.rubrique_infolink { + text-decoration: none; +} + +ul.rubrique_infoul { + display: inline; + list-style-type: square; +} +ul.rubrique_infoul * { + width: 100%; +} +li.rubrique_infoul { + margin-left: 15px; +} +h1 { + color: #990033; +} + +div.main { + background: white; + color: #000000; + margin-left: 5px; + margin-right: 5px; + border: 1px black solid; + text-align: left; + font-size: 12px; +} +div.lsfnbanner { + margin-left: 150px; + margin-right: 170px; + border-top: none; + padding-left: 10px; + padding-right: 10px; + border-bottom: 1px black solid; + border-right: 1px black solid; + border-left: 1px black solid; + text-align: left; + font-size: 11px; + padding-top: 2px; + background-color: #eeeae6; +} +div.footer { + padding-top: 5px; + padding-bottom: 3px; + border-top: 1px black solid; + border-left: 1px black solid; + border-right: 1px black solid; + text-align: left; + font-size: 9px; + background: #dcdff4; + width: 600px; + margin-top: 40px; + margin-left: 20px; +} +div.footer p { + margin-left: 10px; + margin-top: 2px; + margin-bottom: 2px; +} + +a.lsfnlink:link,a.lsfnlink:visited,a.lsfnlink:active { + text-decoration: none; + color: #333333; + font-size: 10px; +} +a.lsfnlink:hover { + text-decoration: underline; + color: black; +} +div.menubartop { + margin-bottom: 10px; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + font-size: 13px; +} +div.smallmenubar { + background: white; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + padding-bottom: 0px; + font-weight:bold; + font-size: 10px; + text-align: right; +} +div.menuevent { + float: left; + width: 350px; + font-size: 11px; + text-align: left; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 10px; + font-weight: bold; + margin: 0px; +} +div.menubar { + background: #cac2a8; + border-top: 1px black solid; + border-bottom: 1px black solid; + padding-left: 10px; + padding-right: 10px; + padding-top: 3px; + padding-bottom: 2px; + font-weight:bold; + font-size: 13px; +} +div.menubar a { + text-decoration: none; +} +div.menudate { + float: left; + width: 130px; + padding-top: 5px; +} +div.menuaccroche { + margin-left: 30px; + float: left; + text-decoration: underline; + font-size: 14px; +} +div.menusearch { + float: right; + text-align: right; + padding-top: 5px; + width: 170px; +} +div.menusearch p { + margin: 0px 0px 0px 0px; +} +.searchinput { + border: solid 1px black; +} +a#menulinkselect { + color: #ed7e00; +} + +div.leftbox { + width: 200px; + float: left; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 5px; + border-right: 1px black solid; + border-bottom: 1px black solid; + background: white; + margin-bottom: 10px; +} +div.leftbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.leftbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.leftbox ul { + list-style-type: square; + margin-bottom: 10px; + margin-left: 0em; + padding-left: 0em; +} +div.leftbox li { + margin-left: 10px; +} + +div.rightbox { + width: 150px; + float: right; + padding-top: 10px; + padding-left: 5px; + padding-right: 15px; + padding-bottom: 5px; + border-left: 1px black solid; + border-bottom: 1px black solid; + text-align: left; +} +div.newjournaldiv { + text-align: justify; + margin-left: 10%; + font-size: 12px; + width: 600px; +} +div.newjournaldiv p { + margin-bottom: 0px; + margin-top: 20px; +} +div.journaldiv { + margin-left: 0px; + margin-right: 0px; + margin-top: 20px; + margin-bottom: 20px; + border: 1px black solid; + padding-top: 5px; + padding-bottom: 5px; + padding-right: 10px; + padding-left: 10px; + background-color: #eef; +} +div.journaldiv p { + margin-top: 10px; + margin-bottom: 0px; +} +div.journaldiv h1 { + color: #990033; + font-size: 14px; + margin: 0px; +} +div.journaldiv h2 { + font-size: 10px; + margin: 0px; +} +div.tipdiv { + margin-left: 220px; + margin-right: 50px; + margin-top: 20px; + padding-top: 5px; + padding-right: 10px; + padding-left: 10px; + text-align: justify; + background-color: #eee; + border: black solid 1px; +} +div.tipdiv h1 { + font-weight: bold; + font-size: 14px; + color: black; + margin-top: 0px; + margin-bottom: 20px; +} +div.tipdiv h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 12px; + margin: 0px; +} + +div.newsdiv { + margin-left: 220px; + margin-right: 180px; + margin-top: 10px; + margin-bottom: 20px; + text-align: justify; +} +div.newsdiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.newsdiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.newsdiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.objdiv { + margin-left: 220px; + margin-right: 20px; + margin-top: 10px; + margin-bottom: 20px; +} + +h1.newstitle { + text-align: left; + font-size: 14px; + margin: 0px 0px 0px 0px; + color: black; +} +div.titlediv { + border-top: solid #cac2a8 2px; + margin-top: 20px; + background-color: #eeeae6; + padding-left: 10px; + font-size: 11px; +} +div.bodydiv { + border: solid #9e9784 1px; + padding-left: 10px; + padding-right: 10px; + padding-top: 10px; + padding-bottom: 5px; + margin-top: 2px; + text-align: justify; +} + +div.comments { + padding: 10px; + border-top: solid 2px #d37537; + border-bottom: solid 2px #d37537; + margin-top: 20px; + margin-bottom: 10px; + background-color: #cacaca; + font-size: 12px; + line-height: 1.3em; +} + +p.commentsbody { + border-left-style: solid; + border-width: 1px; + border-color: rgb(0, 0, 0); + padding-left: 10px; + text-align: justify; + margin-right: 20px; +} + +div.commentsreply { + margin-left: 220px; + text-align: center; + margin-top: 50px; +} + +ul.commentsul { + list-style-type: none; + margin-bottom: 10px; + margin-left: 1.25em; + padding-left: 0em; + border-left: 1px solid black; +} +ul.commentsli { + margin: 10px; +} +div.comments li { + margin-top: 20px; + margin-left: 2px; +} + +div.comments h1 { + font-size: 12px; + color: black; + margin: 0px 20px 3px 0px; + background-color: rgb(226, 226, 226); + padding-left: 1px; + font-weight: none; +} + +div.articlediv { + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 20px; + margin-right: 10px; + margin-left: 220px; + border: solid 1px black; + margin-top: 10px; + text-align: justify; + background-color: #E2E2E2; +} +img { + border: 0px; +} +div.sectionimg { + float: left; + margin-right: 10px; + margin-top: 5px; +} +p.hautpage { + margin-top: 20px; + margin-bottom: 20px; + margin-left: 10px; +} +div.leftcol { + width: 202px; + width: 202px; + float: left; + padding: 0px; +} +div.logodiv { + border-right: 1px black solid; + border-bottom: 1px black solid; + padding: 0px; + line-height: 0px +} +div.loginbox { + margin-left: 4px; + border: solid #a59f8b 1px; + margin-top: 2px; + padding: 5px; + background-color: #fff2e8; + font-size: 10px; +} +div.loginbox p { + margin: 0px; + padding: 0px; +} +div.loginbox ul { + margin-left: 10px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + list-style-type: none; +} +div.loginbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.loginbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.loginbox h3 { + margin-top: 0px; + margin-bottom: 5px; + font-size: 12px; +} +div.polldivtitle { + margin-bottom: 1px; + background-color: #cac2a8; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + font-size: 10px; + border-top: solid #a59f8b 1px; + border-bottom: solid #a59f8b 1px; + text-transform: uppercase; +} +div.polldiv { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + background: #fff2e8; +} +div.polldiv p { +margin: 5px; padding: 0px; +} +div.polldiv ul { + margin-left: 5px; + margin-top: 0px; + margin-bottom: 10px; + padding: 0px; + list-style-type: none; +} +div.otherboxtitle { + margin-bottom: 2px; + background-color: #e3dabc; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + padding-top: 2px; + font-size: 11px; + border-top: solid #777364 1px; + border-bottom: solid #777364 1px; + text-transform: uppercase; + font-weight: bold; +} +div.otherbox { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + text-align: justify; + background: #fff2e8; + font-size: 10px; +} +div.otherbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.otherbox h2 { + font-weight: bold; + font-size: 11px; + margin: 0px; +} +div.otherbox p { + margin-top: 5px; + margin-bottom: 10px; +} +div.rightlogo { + width: 90px; + float: right; + margin-right: 0px; + padding-top: 0px; + padding-left: 0px; + padding-bottom: 0px; +} +div.centraldiv { + margin-left: 220px; + margin-right: 10px; + margin-bottom: 20px; + margin-top: 10px; +} +div.centraldiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.centraldiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.centraldiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.centralinfo { + position:relative; + height:160px; +} +div.lefttopbox { + position:relative; + padding-left: 5px; + padding-right: 5px; + padding-top: 5px; + border: 1px #a59f8b solid; + text-align: justify; + background: #fff2e8; + font-size: 12px; + width: 47%; + float: left; +} +div.lefttopbox p { + margin-top: 5px; margin-bottom: 10px; +} +div.lefttopbox h1 { + font-size: 13px; + font-weight: bold; + margin: 0px; + text-align: right; +} +div.lefttopbox h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.lefttopbox h3 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.righttopbox { + position:relative; + border: 1px #a59f8b solid; + background: white; + padding: 5px; + text-align: justify; + font-size: 12px; + width: 47%; + float: right; +} +div.righttopbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.righttopbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.boardindex { + text-align: justify; + font-size: 11px; + padding: 10px; + margin-left: 20px; + margin-right: 20px; +} +a.boardindex:link,a.boardindex:visited,a.boardindex:active { + text-decoration:none; + color: red; +} +div.boardleftmsg { + float: left; + margin-top: 3px; +} +div.boardrightmsg { + margin-left: 130px; + margin-top: 3px; + padding-left: 5px; +} +div.journalbody { + margin-left: 40px; + margin-top: 40px; +} +div.journalbody h1 { + font-size: 15px; + font-weight: bold; +} +div.journalbody p { + margin-bottom: 20px; +} +.formulaire { + border: solid 1px black; +font-size: 12px; +background-color: #eef; +color: #000000; +} +.newcomments { + color: red; + font-weight: bold; +} +div.commentsreplythanks { + margin-left: 100px; + margin-top: 50px; + margin-right: 100px; + background-color: #eee; + border: black solid 1px; + padding: 10px; +} +div.archivediv { + margin-right: 20px; +} +.archivedate { + color:#f30; +} +.archivelink { + font-size: 14px; + font-weight: bold; + text-decoration: underline; +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test2.css b/src/3rdparty/libcroco/tests/test-inputs/test2.css new file mode 100644 index 0000000..2442048 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test2.css @@ -0,0 +1,9 @@ + +/*simple selector and simple rulset test*/ +S1 {prop1 : value1} + +/*Simple selector list and simple ruleset test*/ +s1,s2 {color: black ; background: white} + +/*descendants and child selector list, simple ruleset test*/ +s1 s2, S3 > s4 {prop1 : value1 ; prop2 : value2} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test3.1.css b/src/3rdparty/libcroco/tests/test-inputs/test3.1.css new file mode 100644 index 0000000..9c53843 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test3.1.css @@ -0,0 +1,36 @@ +S1:lang(c) {prop1 : value1} + +/*simple Attribute set selectors*/ +s1[foo] {prop1 : value1} + +/*simple exact attribute selector, simple ruleset*/ +s1[foo="warning"] {prop1 : value1} + +/** + *"space separated value list" + *attribute selector, simple ruleset + */ +s1[foo~="warning"] {prop1 :value1} + +/** + *"hyphen separated value list" attribute selector, + * simple ruleset + */ + + /*simple class selector, simple ruleset*/ + s1.warning {prop1 : value} + + E#myid {prop1 : value1} + + +/*below are tests that we know are working*/ + +/*simple ident pseudo class selector, simple ruleset test*/ +S1:first-child {prop1 : value1 ; prop2 : value2} + +/*function pseudo class selector, simple ruleset test => merdoie*/ +S1:lang(c) {prop1 : value1} + +/*Adjacent selectors, simple ruleset test*/ +S1 + s2 {prop1: value1} + diff --git a/src/3rdparty/libcroco/tests/test-inputs/test3.2.css b/src/3rdparty/libcroco/tests/test-inputs/test3.2.css new file mode 100644 index 0000000..2857fc4 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test3.2.css @@ -0,0 +1,693 @@ +h1.rubrique_info { + color: #990033; + margin: 0px 0px 0px 0px; + padding: 0em; + border: 0px; + font-size: 12px; +} + +* { + font-family: Verdana, Arial, Helvetica, sans-serif, monospace; +} + +body { + background: #606060; + color: #000000; +} + +a:link { + color: #0000FF; + background: transparent; + text-decoration: none; +} + +a:visited { + color: #990099; + background: transparent; + text-decoration: none; +} + + +a:active { + color: #000000; + background: #ADD8E6; + text-decoration: none; +} + + +h1.rubrique_info { + color: #990033; + margin: 0px 0px 0px 0px; + padding: 0em; + border: 0px; + font-size: 12px; +} + +/* +h1.connexe { + font-size: 12px; + padding: 0em; + margin: 0px 0px 0px 0px; + color: #990033; +} + + +a.rubrique_infolink { + text-decoration: none; +} + + +ul.rubrique_infoul { + display: inline; + list-style-type: square; +} + + +ul.rubrique_infoul * { + width: 100%; +} + +li.rubrique_infoul { + margin-left: 15px; +} +h1 { + color: #990033; +} + +div.main { + background: white; + color: #000000; + margin-left: 5px; + margin-right: 5px; + border: 1px black solid; + text-align: left; + font-size: 12px; +} +div.lsfnbanner { + margin-left: 150px; + margin-right: 170px; + border-top: none; + padding-left: 10px; + padding-right: 10px; + border-bottom: 1px black solid; + border-right: 1px black solid; + border-left: 1px black solid; + text-align: left; + font-size: 11px; + padding-top: 2px; + background-color: #eeeae6; +} +div.footer { + padding-top: 5px; + padding-bottom: 3px; + border-top: 1px black solid; + border-left: 1px black solid; + border-right: 1px black solid; + text-align: left; + font-size: 9px; + background: #dcdff4; + width: 600px; + margin-top: 40px; + margin-left: 20px; +} +div.footer p { + margin-left: 10px; + margin-top: 2px; + margin-bottom: 2px; +} + +a.lsfnlink:link,a.lsfnlink:visited,a.lsfnlink:active { + text-decoration: none; + color: #333333; + font-size: 10px; +} +a.lsfnlink:hover { + text-decoration: underline; + color: black; +} +div.menubartop { + margin-bottom: 10px; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + font-size: 13px; +} +div.smallmenubar { + background: white; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + padding-bottom: 0px; + font-weight:bold; + font-size: 10px; + text-align: right; +} + +div.menuevent { + float: left; + width: 350px; + font-size: 11px; + text-align: left; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 10px; + font-weight: bold; + margin: 0px; +} +div.menubar { + background: #cac2a8; + border-top: 1px black solid; + border-bottom: 1px black solid; + padding-left: 10px; + padding-right: 10px; + padding-top: 3px; + padding-bottom: 2px; + font-weight:bold; + font-size: 13px; +} +div.menubar a { + text-decoration: none; +} +div.menudate { + float: left; + width: 130px; + padding-top: 5px; +} +div.menuaccroche { + margin-left: 30px; + float: left; + text-decoration: underline; + font-size: 14px; +} +div.menusearch { + float: right; + text-align: right; + padding-top: 5px; + width: 170px; +} +div.menusearch p { + margin: 0px 0px 0px 0px; +} +.searchinput { + border: solid 1px black; +} +a#menulinkselect { + color: #ed7e00; +} + +div.leftbox { + width: 200px; + float: left; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 5px; + border-right: 1px black solid; + border-bottom: 1px black solid; + background: white; + margin-bottom: 10px; +} +div.leftbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.leftbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.leftbox ul { + list-style-type: square; + margin-bottom: 10px; + margin-left: 0em; + padding-left: 0em; +} +div.leftbox li { + margin-left: 10px; +} + +div.rightbox { + width: 150px; + float: right; + padding-top: 10px; + padding-left: 5px; + padding-right: 15px; + padding-bottom: 5px; + border-left: 1px black solid; + border-bottom: 1px black solid; + text-align: left; +} +div.newjournaldiv { + text-align: justify; + margin-left: 10%; + font-size: 12px; + width: 600px; +} +div.newjournaldiv p { + margin-bottom: 0px; + margin-top: 20px; +} +div.journaldiv { + margin-left: 0px; + margin-right: 0px; + margin-top: 20px; + margin-bottom: 20px; + border: 1px black solid; + padding-top: 5px; + padding-bottom: 5px; + padding-right: 10px; + padding-left: 10px; + background-color: #eef; +} +div.journaldiv p { + margin-top: 10px; + margin-bottom: 0px; +} +div.journaldiv h1 { + color: #990033; + font-size: 14px; + margin: 0px; +} +div.journaldiv h2 { + font-size: 10px; + margin: 0px; +} +div.tipdiv { + margin-left: 220px; + margin-right: 50px; + margin-top: 20px; + padding-top: 5px; + padding-right: 10px; + padding-left: 10px; + text-align: justify; + background-color: #eee; + border: black solid 1px; +} +div.tipdiv h1 { + font-weight: bold; + font-size: 14px; + color: black; + margin-top: 0px; + margin-bottom: 20px; +} +div.tipdiv h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 12px; + margin: 0px; +} + +div.newsdiv { + margin-left: 220px; + margin-right: 180px; + margin-top: 10px; + margin-bottom: 20px; + text-align: justify; +} +div.newsdiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.newsdiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.newsdiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.objdiv { + margin-left: 220px; + margin-right: 20px; + margin-top: 10px; + margin-bottom: 20px; +} + +h1.newstitle { + text-align: left; + font-size: 14px; + margin: 0px 0px 0px 0px; + color: black; +} +div.titlediv { + border-top: solid #cac2a8 2px; + margin-top: 20px; + background-color: #eeeae6; + padding-left: 10px; + font-size: 11px; +} +div.bodydiv { + border: solid #9e9784 1px; + padding-left: 10px; + padding-right: 10px; + padding-top: 10px; + padding-bottom: 5px; + margin-top: 2px; + text-align: justify; +} + +div.comments { + padding: 10px; + border-top: solid 2px #d37537; + border-bottom: solid 2px #d37537; + margin-top: 20px; + margin-bottom: 10px; + background-color: #cacaca; + font-size: 12px; + line-height: 1.3em; +} + +p.commentsbody { + border-left-style: solid; + border-width: 1px; + border-color: rgb(0, 0, 0); + padding-left: 10px; + text-align: justify; + margin-right: 20px; +} + +div.commentsreply { + margin-left: 220px; + text-align: center; + margin-top: 50px; +} + +ul.commentsul { + list-style-type: none; + margin-bottom: 10px; + margin-left: 1.25em; + padding-left: 0em; + border-left: 1px solid black; +} +ul.commentsli { + margin: 10px; +} +div.comments li { + margin-top: 20px; + margin-left: 2px; +} + +div.comments h1 { + font-size: 12px; + color: black; + margin: 0px 20px 3px 0px; + background-color: rgb(226, 226, 226); + padding-left: 1px; + font-weight: none; +} + +div.articlediv { + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 20px; + margin-right: 10px; + margin-left: 220px; + border: solid 1px black; + margin-top: 10px; + text-align: justify; + background-color: #E2E2E2; +} +img { + border: 0px; +} +div.sectionimg { + float: left; + margin-right: 10px; + margin-top: 5px; +} +p.hautpage { + margin-top: 20px; + margin-bottom: 20px; + margin-left: 10px; +} +div.leftcol { + width: 202px; + width: 202px; + float: left; + padding: 0px; +} +div.logodiv { + border-right: 1px black solid; + border-bottom: 1px black solid; + padding: 0px; + line-height: 0px +} +div.loginbox { + margin-left: 4px; + border: solid #a59f8b 1px; + margin-top: 2px; + padding: 5px; + background-color: #fff2e8; + font-size: 10px; +} +div.loginbox p { + margin: 0px; + padding: 0px; +} +div.loginbox ul { + margin-left: 10px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + list-style-type: none; +} +div.loginbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.loginbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.loginbox h3 { + margin-top: 0px; + margin-bottom: 5px; + font-size: 12px; +} +div.polldivtitle { + margin-bottom: 1px; + background-color: #cac2a8; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + font-size: 10px; + border-top: solid #a59f8b 1px; + border-bottom: solid #a59f8b 1px; + text-transform: uppercase; +} +div.polldiv { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + background: #fff2e8; +} +div.polldiv p { +margin: 5px; padding: 0px; +} +div.polldiv ul { + margin-left: 5px; + margin-top: 0px; + margin-bottom: 10px; + padding: 0px; + list-style-type: none; +} +div.otherboxtitle { + margin-bottom: 2px; + background-color: #e3dabc; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + padding-top: 2px; + font-size: 11px; + border-top: solid #777364 1px; + border-bottom: solid #777364 1px; + text-transform: uppercase; + font-weight: bold; +} +div.otherbox { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + text-align: justify; + background: #fff2e8; + font-size: 10px; +} +div.otherbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.otherbox h2 { + font-weight: bold; + font-size: 11px; + margin: 0px; +} +div.otherbox p { + margin-top: 5px; + margin-bottom: 10px; +} +div.rightlogo { + width: 90px; + float: right; + margin-right: 0px; + padding-top: 0px; + padding-left: 0px; + padding-bottom: 0px; +} +div.centraldiv { + margin-left: 220px; + margin-right: 10px; + margin-bottom: 20px; + margin-top: 10px; +} +div.centraldiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.centraldiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.centraldiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.centralinfo { + position:relative; + height:160px; +} +div.lefttopbox { + position:relative; + padding-left: 5px; + padding-right: 5px; + padding-top: 5px; + border: 1px #a59f8b solid; + text-align: justify; + background: #fff2e8; + font-size: 12px; + width: 47%; + float: left; +} +div.lefttopbox p { + margin-top: 5px; margin-bottom: 10px; +} +div.lefttopbox h1 { + font-size: 13px; + font-weight: bold; + margin: 0px; + text-align: right; +} +div.lefttopbox h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.lefttopbox h3 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.righttopbox { + position:relative; + border: 1px #a59f8b solid; + background: white; + padding: 5px; + text-align: justify; + font-size: 12px; + width: 47%; + float: right; +} +div.righttopbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.righttopbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.boardindex { + text-align: justify; + font-size: 11px; + padding: 10px; + margin-left: 20px; + margin-right: 20px; +} +a.boardindex:link,a.boardindex:visited,a.boardindex:active { + text-decoration:none; + color: red; +} +div.boardleftmsg { + float: left; + margin-top: 3px; +} +div.boardrightmsg { + margin-left: 130px; + margin-top: 3px; + padding-left: 5px; +} +div.journalbody { + margin-left: 40px; + margin-top: 40px; +} +div.journalbody h1 { + font-size: 15px; + font-weight: bold; +} +div.journalbody p { + margin-bottom: 20px; +} + +.formulaire { + border: solid 1px black; +font-size: 12px; +background-color: #eef; +color: #000000; +} +.newcomments { + color: red; + font-weight: bold; +} +div.commentsreplythanks { + margin-left: 100px; + margin-top: 50px; + margin-right: 100px; + background-color: #eee; + border: black solid 1px; + padding: 10px; +} +div.archivediv { + margin-right: 20px; +} +.archivedate { + color:#f30; +} +.archivelink { + font-size: 14px; + font-weight: bold; + text-decoration: underline; +} +*/
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-inputs/test3.css b/src/3rdparty/libcroco/tests/test-inputs/test3.css new file mode 100644 index 0000000..2442048 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test3.css @@ -0,0 +1,9 @@ + +/*simple selector and simple rulset test*/ +S1 {prop1 : value1} + +/*Simple selector list and simple ruleset test*/ +s1,s2 {color: black ; background: white} + +/*descendants and child selector list, simple ruleset test*/ +s1 s2, S3 > s4 {prop1 : value1 ; prop2 : value2} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test4.1.css b/src/3rdparty/libcroco/tests/test-inputs/test4.1.css new file mode 100644 index 0000000..01bd9d4 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test4.1.css @@ -0,0 +1,682 @@ +* { + font-family: Verdana, Arial, Helvetica, sans-serif, monospace !important; +} + +tutu:class1:class2 { + test:ok ; +} + +body { + background: #606060; + color: #000000; +} + + +a:link { + color: #0000FF; + background: transparent; + text-decoration: none; +} + + +a:visited { + color: #990099; + background: transparent; + text-decoration: none; +} + + +a:active { + color: #000000; + background: #ADD8E6; + text-decoration: none; +} + +h1.rubrique_info { + color: #990033; + margin: 0px 0px 0px 0px; + padding: 0.4em; + border: 0px; + font-size: 12px; +} +h1.connexe { + font-size: 12px; + padding: 0.9em; + margin: 0px 0px 0px 0px; + color: #990033; +} + +a.rubrique_infolink { + text-decoration: none; +} + +ul.rubrique_infoul { + display: inline; + list-style-type: square; +} +ul.rubrique_infoul * { + width: 100%; +} +li.rubrique_infoul { + margin-left: 15px; +} +h1 { + color: #990033; +} + +div.main { + background: white; + color: #000000; + margin-left: 5px; + margin-right: 5px; + border: 1px black solid; + text-align: left; + font-size: 12px; +} +div.lsfnbanner { + margin-left: 150px; + margin-right: 170px; + border-top: none; + padding-left: 10px; + padding-right: 10px; + border-bottom: 1px black solid; + border-right: 1px black solid; + border-left: 1px black solid; + text-align: left; + font-size: 11px; + padding-top: 2px; + background-color: #eeeae6; +} +div.footer { + padding-top: 5px; + padding-bottom: 3px; + border-top: 1px black solid; + border-left: 1px black solid; + border-right: 1px black solid; + text-align: left; + font-size: 9px; + background: #dcdff4; + width: 600px; + margin-top: 40px; + margin-left: 20px; +} +div.footer p { + margin-left: 10px; + margin-top: 2px; + margin-bottom: 2px; +} + +a.lsfnlink:link,a.lsfnlink:visited,a.lsfnlink:active { + text-decoration: none; + color: #333333; + font-size: 10px; +} +a.lsfnlink:hover { + text-decoration: underline; + color: black; +} +div.menubartop { + margin-bottom: 10px; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + font-size: 13px; +} +div.smallmenubar { + background: white; + padding-left: 10px; + padding-right: 10px; + padding-top: 0px; + padding-bottom: 0px; + font-weight:bold; + font-size: 10px; + text-align: right; +} +div.menuevent { + float: left; + width: 350px; + font-size: 11px; + text-align: left; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 10px; + font-weight: bold; + margin: 0px; +} +div.menubar { + background: #cac2a8; + border-top: 1px black solid; + border-bottom: 1px black solid; + padding-left: 10px; + padding-right: 10px; + padding-top: 3px; + padding-bottom: 2px; + font-weight:bold; + font-size: 13px; +} +div.menubar a { + text-decoration: none; +} +div.menudate { + float: left; + width: 130px; + padding-top: 5px; +} +div.menuaccroche { + margin-left: 30px; + float: left; + text-decoration: underline; + font-size: 14px; +} +div.menusearch { + float: right; + text-align: right; + padding-top: 5px; + width: 170px; +} +div.menusearch p { + margin: 0px 0px 0px 0px; +} +.searchinput { + border: solid 1px black; +} +a#menulinkselect { + color: #ed7e00; +} + +div.leftbox { + width: 200px; + float: left; + padding-left: 5px; + padding-right: 5px; + padding-bottom: 5px; + border-right: 1px black solid; + border-bottom: 1px black solid; + background: white; + margin-bottom: 10px; +} +div.leftbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.leftbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.leftbox ul { + list-style-type: square; + margin-bottom: 10px; + margin-left: 0.3em; + padding-left: 0.2em; +} +div.leftbox li { + margin-left: 10px; +} + +div.rightbox { + width: 150px; + float: right; + padding-top: 10px; + padding-left: 5px; + padding-right: 15px; + padding-bottom: 5px; + border-left: 1px black solid; + border-bottom: 1px black solid; + text-align: left; +} +div.newjournaldiv { + text-align: justify; + margin-left: 10%; + font-size: 12px; + width: 600px; +} +div.newjournaldiv p { + margin-bottom: 0px; + margin-top: 20px; +} +div.journaldiv { + margin-left: 0px; + margin-right: 0px; + margin-top: 20px; + margin-bottom: 20px; + border: 1px black solid; + padding-top: 5px; + padding-bottom: 5px; + padding-right: 10px; + padding-left: 10px; + background-color: #eef; +} +div.journaldiv p { + margin-top: 10px; + margin-bottom: 0px; +} +div.journaldiv h1 { + color: #990033; + font-size: 14px; + margin: 0px; +} +div.journaldiv h2 { + font-size: 10px; + margin: 0px; +} +div.tipdiv { + margin-left: 220px; + margin-right: 50px; + margin-top: 20px; + padding-top: 5px; + padding-right: 10px; + padding-left: 10px; + text-align: justify; + background-color: #eee; + border: black solid 1px; +} +div.tipdiv h1 { + font-weight: bold; + font-size: 14px; + color: black; + margin-top: 0px; + margin-bottom: 20px; +} +div.tipdiv h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 12px; + margin: 0px; +} + +div.newsdiv { + margin-left: 220px; + margin-right: 180px; + margin-top: 10px; + margin-bottom: 20px; + text-align: justify; +} +div.newsdiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.newsdiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.newsdiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.objdiv { + margin-left: 220px; + margin-right: 20px; + margin-top: 10px; + margin-bottom: 20px; +} + +h1.newstitle { + text-align: left; + font-size: 14px; + margin: 0px 0px 0px 0px; + color: black; +} +div.titlediv { + border-top: solid #cac2a8 2px; + margin-top: 20px; + background-color: #eeeae6; + padding-left: 10px; + font-size: 11px; +} +div.bodydiv { + border: solid #9e9784 1px; + padding-left: 10px; + padding-right: 10px; + padding-top: 10px; + padding-bottom: 5px; + margin-top: 2px; + text-align: justify; +} + +div.comments { + padding: 10px; + border-top: solid 2px #d37537; + border-bottom: solid 2px #d37537; + margin-top: 20px; + margin-bottom: 10px; + background-color: #cacaca; + font-size: 12px; + line-height: 1.3em; +} + + +p.commentsbody { + border-left-style: solid; + border-width: 1px; + border-color: rgb(0, 0, 0); + padding-left: 10px; + text-align: justify; + margin-right: 20px; +} + + +div.commentsreply { + margin-left: 220px; + text-align: center; + margin-top: 50px; +} + +ul.commentsul { + list-style-type: none; + margin-bottom: 10px; + margin-left: 1.25em; + padding-left: 0em; + border-left: 1px solid black; +} +ul.commentsli { + margin: 10px; +} +div.comments li { + margin-top: 20px; + margin-left: 2px; +} + +div.comments h1 { + font-size: 12px; + color: black; + margin: 0px 20px 3px 0px; + background-color: rgb(226, 226, 226); + padding-left: 1px; + font-weight: none; +} + +div.articlediv { + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 20px; + margin-right: 10px; + margin-left: 220px; + border: solid 1px black; + margin-top: 10px; + text-align: justify; + background-color: #E2E2E2; +} +img { + border: 0px; +} +div.sectionimg { + float: left; + margin-right: 10px; + margin-top: 5px; +} +p.hautpage { + margin-top: 20px; + margin-bottom: 20px; + margin-left: 10px; +} +div.leftcol { + width: 202px; + width: 202px; + float: left; + padding: 0px; +} +div.logodiv { + border-right: 1px black solid; + border-bottom: 1px black solid; + padding: 0px; + line-height: 0px +} +div.loginbox { + margin-left: 4px; + border: solid #a59f8b 1px; + margin-top: 2px; + padding: 5px; + background-color: #fff2e8; + font-size: 10px; +} +div.loginbox p { + margin: 0px; + padding: 0px; +} +div.loginbox ul { + margin-left: 10px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + list-style-type: none; +} +div.loginbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.loginbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.loginbox h3 { + margin-top: 0px; + margin-bottom: 5px; + font-size: 12px; +} +div.polldivtitle { + margin-bottom: 1px; + background-color: #cac2a8; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + font-size: 10px; + border-top: solid #a59f8b 1px; + border-bottom: solid #a59f8b 1px; + text-transform: uppercase; +} +div.polldiv { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + background: #fff2e8; +} +div.polldiv p { +margin: 5px; padding: 0px; +} +div.polldiv ul { + margin-left: 5px; + margin-top: 0px; + margin-bottom: 10px; + padding: 0px; + list-style-type: none; +} +div.otherboxtitle { + margin-bottom: 2px; + background-color: #e3dabc; + margin-left: 4px; + margin-top: 15px; + padding-left: 5px; + padding-top: 2px; + font-size: 11px; + border-top: solid #777364 1px; + border-bottom: solid #777364 1px; + text-transform: uppercase; + font-weight: bold; +} +div.otherbox { + margin-left: 4px; + border: 1px #a59f8b solid; + margin-top: 0px; + padding: 5px; + text-align: justify; + background: #fff2e8; + font-size: 10px; +} +div.otherbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.otherbox h2 { + font-weight: bold; + font-size: 11px; + margin: 0px; +} +div.otherbox p { + margin-top: 5px; + margin-bottom: 10px; +} +div.rightlogo { + width: 90px; + float: right; + margin-right: 0px; + padding-top: 0px; + padding-left: 0px; + padding-bottom: 0px; +} +div.centraldiv { + margin-left: 220px; + margin-right: 10px; + margin-bottom: 20px; + margin-top: 10px; +} +div.centraldiv h1 { + font-weight: bold; + font-size: 14px; + margin: 0px; +} +div.centraldiv h2 { + font-weight: normal; + font-size: 12px; + margin: 0px; +} +div.centraldiv h3 { + font-weight: normal; + font-size: 12px; + margin-bottom: 20px; +} +div.centralinfo { + position:relative; + height:160px; +} +div.lefttopbox { + position:relative; + padding-left: 5px; + padding-right: 5px; + padding-top: 5px; + border: 1px #a59f8b solid; + text-align: justify; + background: #fff2e8; + font-size: 12px; + width: 47%; + float: left; +} +div.lefttopbox p { + margin-top: 5px; margin-bottom: 10px; +} +div.lefttopbox h1 { + font-size: 13px; + font-weight: bold; + margin: 0px; + text-align: right; +} +div.lefttopbox h2 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.lefttopbox h3 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.righttopbox { + position:relative; + border: 1px #a59f8b solid; + background: white; + padding: 5px; + text-align: justify; + font-size: 12px; + width: 47%; + float: right; +} +div.righttopbox h1 { + text-transform: uppercase; + font-weight: bold; + color: #ed7e00; + font-size: 10px; + margin: 0px; +} +div.righttopbox h2 { + font-weight: bold; + font-size: 12px; + margin: 0px; +} +div.boardindex { + text-align: justify; + font-size: 11px; + padding: 10px; + margin-left: 20px; + margin-right: 20px; +} +a.boardindex:link,a.boardindex:visited,a.boardindex:active { + text-decoration:none; + color: red; +} +div.boardleftmsg { + float: left; + margin-top: 3px; +} +div.boardrightmsg { + margin-left: 130px; + margin-top: 3px; + padding-left: 5px; +} +div.journalbody { + margin-left: 40px; + margin-top: 40px; +} +div.journalbody h1 { + font-size: 15px; + font-weight: bold; +} +div.journalbody p { + margin-bottom: 20px; +} +.formulaire { + border: solid 1px black; +font-size: 12px; +background-color: #eef; +color: #000000; +} +.newcomments { + color: red; + font-weight: bold; +} +div.commentsreplythanks { + margin-left: 100px; + margin-top: 50px; + margin-right: 100px; + background-color: #eee; + border: black solid 1px; + padding: 10px; +} +div.archivediv { + margin-right: 20px; +} +.archivedate { + color:#f30; +} +.archivelink { + font-size: 14px; + font-weight: bold; + text-decoration: underline; +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test4.2.css b/src/3rdparty/libcroco/tests/test-inputs/test4.2.css new file mode 100644 index 0000000..2dafbef --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test4.2.css @@ -0,0 +1,24 @@ +@charset "ISO-8859-1" ; + +@import url("http://www.yahoo.com/css") print , screen ; + +@font-face { + font-family: "Robson Celtic"; + src: url("http://site/fonts/rob-celt") +} + + + +@page left:one-two { + margin: 10pt; + border:none +} + +@media print , screen , projection { + H1 { font-family: "Robson Celtic", serif } + + P { + background: black ; + foreground: white ; + } +} diff --git a/src/3rdparty/libcroco/tests/test-inputs/test5.1.css b/src/3rdparty/libcroco/tests/test-inputs/test5.1.css new file mode 100644 index 0000000..26c3627 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/test5.1.css @@ -0,0 +1,14 @@ +.class5 {prop8: val8} +#id6 {prop9: val9} +[attr4|=val4] {prop7: val7} +[attr3~=val3_2] {prop6: val6} +[attr2=val2] {prop5: val5} +:first-child {first-child-prop: first-child-value} +:lang(fr) {lang-prop: lang-value} +E2[attr2=val2] {prop8: val8} +E0 {prop0: val0} +E0+E1{pro1:val1} +E1 E1-1 {prop2: val2} +E1 > E1-1 {prop3: val3} +document E1-1 {prop4: val4} + diff --git a/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule.css b/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule.css new file mode 100644 index 0000000..7680999 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule.css @@ -0,0 +1,3 @@ +@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace +to +HTML */
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule2.css b/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule2.css new file mode 100644 index 0000000..0c4a191 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-inputs/unknown-at-rule2.css @@ -0,0 +1,3 @@ +@namespace url(http://www.w3.org/1999/xhtml); dummyrule { } /* set +default +namespace to HTML */
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-lots-of-comments.sh b/src/3rdparty/libcroco/tests/test-lots-of-comments.sh new file mode 100755 index 0000000..f2eae9b --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-lots-of-comments.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT $TEST_INPUTS_DIR/lots-of-comments.css diff --git a/src/3rdparty/libcroco/tests/test-output-refs/Makefile.am b/src/3rdparty/libcroco/tests/test-output-refs/Makefile.am new file mode 100644 index 0000000..b113e7f --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/Makefile.am @@ -0,0 +1,16 @@ +EXTRA_DIST=test0.1.css.out \ +test1.css.out \ +test2.1.css.out \ +test2.2.css.out \ +test2.css.out \ +test3.1.css.out \ +test3.2.css.out \ +test3.css.out \ +test4.1.css.out \ +test4.2.css.out \ +test6.out \ +test-prop-ident.out \ +test-unknown-at-rule.out \ +test-unknown-at-rule2.out \ +test-several-media.out \ +test5.1.css.out diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-functional-notation.out b/src/3rdparty/libcroco/tests/test-output-refs/test-functional-notation.out new file mode 100644 index 0000000..7fa05fd --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-functional-notation.out @@ -0,0 +1,7 @@ +foo { + bar : attr(width, length, calc(70% -5px)) +} + +foo { + bar : attr(x, y) +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-lots-of-comments.out b/src/3rdparty/libcroco/tests/test-output-refs/test-lots-of-comments.out new file mode 100644 index 0000000..59b08ef --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-lots-of-comments.out @@ -0,0 +1,26 @@ +@charset "utf8" ; + +@import url("http://pouet.com")screen, paper, aural ; + +@page coin :pseudo-page { + page-prop0 : page-val0; + page-prop1 : page-val1 +} + + +@media paper, aural { + x { + foo : fooval; + bar : barval + } +} + +@font-face { + font-prop1 : font1; + font-prop2 : font2 +} + +x>y[attr="val"].class#tatati z+toto { + prop1 : function(a); + prop2 : val2 +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-parsing-location.out b/src/3rdparty/libcroco/tests/test-output-refs/test-parsing-location.out new file mode 100644 index 0000000..7be4584 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-parsing-location.out @@ -0,0 +1,219 @@ + + +@charset "utf8"; + +/******************************************** + * Parsing location information of the @charset rule + ********************************************/ + /*@charset*/ + /*line:1 column:1 byte offset:0 */ + /*utf8*/ + /*line:1 column:10 byte offset:9 */ + +@import url("http://pouet.com") screen, paper, aural; + +/***************************************************** + *Parsing location information for the @import rule + ******************************************************/ + + /*@import*/ + /*line:3 column:1 byte offset:19 */ + + /*http://pouet.com*/ + /*line:3 column:9 byte offset:27 */ + + /*screen*/ + /*line:3 column:33 byte offset:51 */ + + /*paper*/ + /*line:3 column:41 byte offset:59 */ + + /*aural*/ + /*line:3 column:48 byte offset:66 */ + +@import url("http://pouet.com") screen2, paper2, aural2; + +/***************************************************** + *Parsing location information for the @import rule + ******************************************************/ + + /*@import*/ + /*line:4 column:1 byte offset:74 */ + + /*http://pouet.com*/ + /*line:4 column:9 byte offset:82 */ + + /*screen2*/ + /*line:4 column:31 byte offset:104 */ + + /*paper2*/ + /*line:4 column:40 byte offset:113 */ + + /*aural2*/ + /*line:4 column:48 byte offset:121 */ + +@page coin :pseudo-page + + /*@page*/ + /*line:6 column:1 byte offset:131 */ + /*coin*/ + /*line:6 column:7 byte offset:137 */ + /*pseudo-page*/ + /*line:6 column:13 byte offset:143 */ + +{ + + +page-prop0 : page-val0; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*page-prop0*/ + /*line:7 column:7 byte offset:163 */ + /*page-val0*/ + /*line:7 column:19 byte offset:175 */ + + +page-prop1 : page-val1; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*page-prop1*/ + /*line:8 column:7 byte offset:193 */ + /*page-val1*/ + /*line:8 column:19 byte offset:205 */ +} +@media paper, aural + /*@media*/ + /*line:11 column:1 byte offset:220 */ + /*paper*/ + /*line:11 column:8 byte offset:227 */ + /*aural*/ + /*line:11 column:15 byte offset:234 */ + +{ +x { +/************************************************ + *Parsing location information of the selector + ************************************************/ +/*x*/ +/*line:12 column:5 byte offset:246 */ + /*x*/ + /*line:12 column:5 byte offset:246 */ + + +foo : fooval; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*foo*/ + /*line:13 column:7 byte offset:256 */ + /*fooval*/ + /*line:13 column:12 byte offset:261 */ + + +bar : barval; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*bar*/ + /*line:14 column:7 byte offset:276 */ + /*barval*/ + /*line:14 column:12 byte offset:281 */ + } + +} +@font-face { +/****************************************************** + Parsing location information for the @font-face rule + ******************************************************/ + + /*@font-face*/ + /*line:18 column:1 byte offset:299 */ + + +font-prop1 : font1; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*font-prop1*/ + /*line:19 column:2 byte offset:313 */ + /*font1*/ + /*line:19 column:14 byte offset:325 */ + + +font-prop2 : font2; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*font-prop2*/ + /*line:20 column:2 byte offset:334 */ + /*font2*/ + /*line:20 column:14 byte offset:346 */ +} +x>y[attr="val"].class#tatati z+toto { +/************************************************ + *Parsing location information of the selector + ************************************************/ +/*x*/ +/*line:22 column:1 byte offset:356 */ + /*x*/ + /*line:22 column:1 byte offset:356 */ +/*y[attr="val"].class#tatati*/ +/*line:22 column:5 byte offset:360 */ + /*y*/ + /*line:22 column:5 byte offset:360 */ + + /*[attr="val"]*/ + /*line:22 column:6 byte offset:361 */ + + /*.class*/ + /*line:22 column:17 byte offset:372 */ + + /*#tatati*/ + /*line:22 column:22 byte offset:377 */ +/*z*/ +/*line:22 column:30 byte offset:385 */ + /*z*/ + /*line:22 column:30 byte offset:385 */ +/*toto*/ +/*line:22 column:34 byte offset:389 */ + /*toto*/ + /*line:22 column:34 byte offset:389 */ + + +prop1 : function(a); + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*prop1*/ + /*line:23 column:2 byte offset:396 */ + /*function(a)*/ + /*line:23 column:9 byte offset:403 */ + + +prop2 : val2; + + +/************************************************ + *Parsing location information of the property + ************************************************/ + /*prop2*/ + /*line:24 column:2 byte offset:418 */ + /*val2*/ + /*line:24 column:9 byte offset:425 */ + } diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-prop-ident.out b/src/3rdparty/libcroco/tests/test-output-refs/test-prop-ident.out new file mode 100644 index 0000000..149e8f5 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-prop-ident.out @@ -0,0 +1,3 @@ +:-foo-pseudo { + -foo-bar-prop : -foobar-value +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-sel-child-class.out b/src/3rdparty/libcroco/tests/test-output-refs/test-sel-child-class.out new file mode 100644 index 0000000..aadd508 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-sel-child-class.out @@ -0,0 +1,4 @@ +Properties of xml element p are: + color : aqua +===================== + diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-several-media.out b/src/3rdparty/libcroco/tests/test-output-refs/test-several-media.out new file mode 100644 index 0000000..4b3cbdd --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-several-media.out @@ -0,0 +1,17 @@ +@media screen { + a:link { + text-decoration : none + } + div { + width : 50% + } +} + +@media print { + a { + color : red + } + div { + width : 57% + } +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule.out b/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule.out new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule.out @@ -0,0 +1 @@ + diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule2.out b/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule2.out new file mode 100644 index 0000000..a356a7d --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test-unknown-at-rule2.out @@ -0,0 +1,2 @@ +dummyrule { +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test0.1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test0.1.css.out new file mode 100644 index 0000000..16475bd --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test0.1.css.out @@ -0,0 +1 @@ +9811110012132123103232109971141031051103258324811212032481121203250481121203248112120591032321041011051031041163258324948483759103232989799107103114111117110100325832357070701012510106532123103232991111081111143258323548485151545459103232116101120116451001019911111497116105111110325832117110100101114108105110101101251010655810810511010732123103232991111081111143258323548485151545459103232116101120116451001019911111497116105111110325832117110100101114108105110101101251010655811810511510511610110032123103232991111081111143258323548485151545459103232116101120116451001019911111497116105111110325832117110100101114108105110101101251010655897991161051181013212310323299111108111114325832355757575757571012510106558104111118101114321231032329911110811111432583235575757575757101251010104494432104504432104513212310323210997114103105110325832481121205910323211297100100105110103325832481121201012510103598971101101011143212310323210211111011645102971091051081213258321129710897116105110111443210310111111410310597443211810111410097110974432971141059710844321159711011545115101114105102591032329911110811111432583235515151591032321161111125848591032321021111101164511510512210132583211011111410997108591032321021111101164511910110510310411632583211011111410997108591012510103598971101101011143297443235989711011010111432975810810511010744323598971101101011143297581181051151051161011004432359897110110101114329758979911610511810144323598971101101011143297581041111181011143212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232102111110116451151051221013258321201204510897114103101591032329911110811111432583235515151591032321161011201164510010199111114971161051111103258321101111101011012510104610010111599114105112116105111110321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323299111108111114325832355151515910323210211111011645115105122101325832115109971081085910323211610112011645116114971101151021111141093258321101111101011012510103599111110116101110116321231032321121111151051161051111103258329798115111108117116101591032329897991071031141111171101003258323570707059103232116111112583250483759321032321081011021165832504837591032329811111410010111432583249112120321151111081051003235707070101251010359911111011697105110101114321231032329897991071031141111171101003258323570707059103232981111141001011143258324911212032115111108105100323570707010125101035108105110107115321231032321129710010010511010332583249531121205910323298111114100101114325832491121203211511110810510032357070705910323211910510011610432583250484811212010125101046981081111033212310323211297100100105110103325832504811212059103232989799107103114111117110100325832357070701012510104698108111103981111001213212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232991111081111143258323551515159103232102111110116451151051221013258321151099710810859103232102111110116451191011051031041163258321101111141099710859103232989799107103114111117110100325832357070705910323210810511010145104101105103104116325832495348371012510104698108111103981111001213297443246981081111039811110012132975810810511010744324698108111103981111001213297581181051151051161011004432469810811110398111100121329758979911610511810144324698108111103981111001213297581041111181011143212310323210211111011645119101105103104116325832110111114109971085910323211610112011645100101991111149711610511111032583211711010010111410810511010110125101046116105116108101321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323210211111011645115105122101325832109101100105117109591032329911110811111432583235545454101251010461009711610132123103232102111110116451029710910510812132583211810111410097110974432971141059710844321151011141051025910323210211111011645115105122101325832108971141031015910323299111108111114325832355151515910323298111114100101114459811111611611110932583249112120321151111081051003235575757591032321099711410310511045981111161161111093258324948112120591032321021111101164511910110510310411632583298111108100101251010461121111151161011003212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232102111110116451151051221013258321204511510997108108591032329911110811111432583235484848484848591032321099711410310511045981111161161111093258325053112120101251010469997108101110100971143212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232991111081111143258323551515159103232102111110116451151051221013258321204511510997108108591032321021111101164511910110510310411632583211011111410997108591032329897991071031141111171101003258323570707059103232108105110101451041011051031041163258324952483759103232112971001001051101033258325011212059103232116101120116459710810510311032583210810110211610125101046999710810111010097114104101971003212310323210211111011645102971091051081213258321129710897116105110111443210310111111410310597443211610510910111532110101119321141111099711044321151011141051025910323299111108111114325832355454545448485910323210211111011645115105122101325832115109971081085910323210211111011645119101105103104116325832110111114109971085910323211297100100105110103325832501121205910323210810111611610111445115112979910511010332583248465110110959103232989799107103114111117110100325832357070705910323211610112011645116114971101151021111141093258321171121121011149997115101591032321161011201164597108105103110325832108101102116101251010461151051001013212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232991111081111143258323551515159103232102111110116451151051221013258321204511510997108108591032321021111101164511910110510310411632583211011111410997108591032329897991071031141111171101003258323570707059103232108105110101451041011051031041163258324952483759103232112971001001051101033258325011212010125101035109101110117989711432123103232102111110116451029710910510812132583211810111410097110974432971141059710844321159711011545115101114105102591032329911110811111432583235515151591032321021111101164511510512210132583211510997108108591032321021111101164511910110510310411632583211011111410997108591032321121111151051161051111105897981151111081171161015910323211611111258504837591032321129710010010511010358325011212059103232108101116116101114451151129799105110103325832484649101109591032329897991071031141111171101003258323570707059103232116101120116451161149711011510211111410932583211711211210111499971151011012510104611512111010010599971161013212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232102111110116451151051221013258321201204511510997108108591032321081051101014510410110510310411632583249524837591032321129710010010511010332583250112120591032321099711410310511045116111112325832495311212059103232989799107103114111117110100325832357070701012510104611211111910111410110032123103232102111110116451029710910510812132583211810111410097110974432971141059710844321159711011545115101114105102591032329911110811111432583235545454591032321021111101164511510512210132583212045115109971081085910323210810511010145104101105103104116325832495248375910323211610112011645116114971101151021111141093258321171121121011149997115101591032321129710010010511010332583250112120591032321099711410310511045116111112325832534811212059103232108101116116101114451151129799105110103325832484650101109591032329897991071031141111171101003258323570707010125101046991111091091011101161154598111100121321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323299111108111114325832355454545910323210211111011645115105122101325832115109971081085910323210211111011645119101105103104116325832110111114109971085910323298979910710311411111711010032583235707070591032321081051101014510410110510310411632583249524837591032321129710010010511010345981111161161111093258324948112120591032321129710010010511010345116111112325832494811212059103232981111141001011144598111116116111109325832491121203210011111611610110032355757571012510104699111109109101110116115451121111151163212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232991111081111143258323554545459103232102111110116451151051221013258321204511510997108108591032321021111101164511910110510310411632583211011111410997108591032329897991071031141111171101003258323570707010125101046116114979910798979910745117114108321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323299111108111114325832355454545910323210211111011645115105122101325832115109971081085910323210211111011645119101105103104116325832110111114109971085910323298979910710311411111711010032583235707070591032321081051101014510410110510310411632583249524837591032321129710010010511010332583253112120591032329811111410010111432583249112120321001111161161011003235575757101251010461161149799107989799107459811110012132123103232102111110116451029710910510812132583211810111410097110974432971141059710844321159711011545115101114105102591032329911110811111432583235545454591032321021111101164511510512210132583211510997108108591032321021111101164511910110510310411632583211011111410997108591032329897991071031141111171101003258323570707059103232108105110101451041011051031041163258324952483759103232112971001001051101034598111116116111109325832494811212059103232112971001001051101034511611111232583249481121205910323298111114100101114459811111611611110932583249112120321001111161161011003235575757101251010461161149799107989799107451121111151163212310323210211111011645102971091051081213258321181011141009711097443297114105971084432115971101154511510111410510259103232991111081111143258323554545459103232102111110116451151051221013258321204511510997108108591032321021111101164511910110510310411632583211011111410997108591032329897991071031141111171101003258323570707010125101046991111091091011101161154510410197100321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323210211111011645115105122101325832115109971081085910323299111108111114325832355454545910323298111114100101114459811111611611110932583249112120321151111081051003235575757591032321099711410310511045116111112325832504811212059103232102111110116451191011051031041163258329811110810059103232989799107103114111117110100325832357070701012510103598971101101011144599111109109101110116115112111112321231032321021111101164510297109105108121325832118101114100971109744329711410597108443211597110115451151011141051025910323299111108111114325832357070705910323210211111011645115105122101325832108971141031015910323210211111011645119101105103104116325832981111081005910323298111114100101114451081011021163258324911212032115111108105100323570707059103232981111141001011144511410510310411632583249112120321151111081051003235707070591032329811111410010111445116111112325832491121203211511110810510032357070705910323298979910710311411111711010032583235484851515454591032321129710010010511010345108101102116325832495311212059103232112971001001051101034511410510310411632583249531121205910323211297100100105110103451161111123258325311212059103232112971001001051101034598111116116111109325832531121201012510
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test1.css.out new file mode 100644 index 0000000..b03c8a4 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test1.css.out @@ -0,0 +1,316 @@ +body { + + background-color: #E5E5E5; + + scrollbar-face-color: #CCCCCC; + + scrollbar-highlight-color: #FFFFFF; + + scrollbar-shadow-color: #CCCCCC; + + scrollbar-3dlight-color: #D1D7DC; + + scrollbar-arrow-color: #000000; + + scrollbar-track-color: #FFFFFF; + + scrollbar-darkshadow-color: #000000; + +} + + + +font, th, td, p { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + +} + + + +h1, h2 { font-size: 11px; color: #000000; font-weight: bold; } + + + +a:link, a:active, a:visited { color: #000000; } + + + +a:hover { color: #CC0000; text-decoration: underline; } + + + +hr { height: 0px; border: solid #CCCCCC 0px; border-top-width: 1px; } + + + +small { font-size: 10px; } + + + +input, textarea, select { + + font: normal 11px Verdana, Arial, Helvetica, sans-serif; + + color: #000000; + + border-color: #000000; + +} + + + +input { text-indent: 2px; } + + + + +input.post, textarea.post, select { + + background-color: #FFFFFF; + +} + + + + +th { + + font-size: 11px; color: #CCCCCC; font-weight: bold; + + background-color: #000000; height: 25px; + + background-image: url(/~wiceyto/test/templates/blacknwhite/images/cellpic3.gif); + +} + + + + +.fontspec, .tablefont { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + +} + + + +.navbartext, .navbarfont { + + font-size: 11px; color: #000000; font-weight: bold; + +} + + + +.navbartext a, .navbarfont a { + + color: #000000; font-weight: bold; text-decoration: none; + +} + + + +.navbartext a:hover, .navbarfont a:hover { + + color: #CC0000; text-decoration: none; + +} + + + +.tablespec, .guestbook { background-color: #FFFFFF; border: 2px #000000 solid; } + +.tablespec th, .tablespec td { color: #000000; background-color: #CCCCCC; } + +.tablespec th { background-image: none; } + + + +.messageblock { + + border: dashed 1px; + + margin-right: 4em; margin-left: 4em; + + padding: 3em; + +} + + + +/* $MessageOpenCode - the body of text of the posts */ + +.messagebody { font-size: 12px; line-height: 18px; } + +.messagebody a { color: #000000; text-decoration: underline; } + +.messagebody a:hover { color: #CC0000; text-decoration: underline; } + + + + +.newcode { font-size: 11px; color: #CC0000; font-weight: bold; } + +.admincode { font-size: 11px; color: #990000; font-style: bold; } + + + + +.bodyline { background-color: #FFFFFF; border: 1px #000000 solid; } + + + + +.quote, .code { + + background-color: #FAFAFA; border: #D1D7DC; border-style: solid; + + border-top-width: 1px; border-right-width: 1px; + + border-bottom-width: 1px; border-left-width: 1px; + +} + + + +.quote { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + + color: #444444; line-height: 125%; + +} + + + +.code { + + font-family: Courier, 'Courier New', sans-serif; + + font-size: 11px; + + color: #CC0000; + +} + + + + +input.button { + + font-family: Verdana, Arial, Helvetica, sans-serif; + + font-size: 11px; + + color: #000000; + + background-color: #FFFFFF; + +} + + + +/* Format button rollover help line. Actually it's a text box + + set to the same color as the background so no one will know. */ + +.helpline { background-color: #CCCCCC; border-style: none; } + + + +/* additional table cell colors and backgrounds */ + +td.row2 { background-color: #CCCCCC; } + +td.row1 { background-color: #CCCCCC; } + +td.row3 { background-color: #D1D7DC; } + + + +/* additional general text */ + +.gen { font-size: 12px; } + +.genmed { font-size: 11px; } + +.gensmall { font-size: 10px; } + +.gen, .genmed, .gensmall { color: #000000; } + +a.gen, a.genmed, a.gensmall { color: #000000; text-decoration: none; } + +a.gen:hover, a.genmed:hover, a.gensmall:hover { color: #CC0000; text-decoration: underline; } + + + +/* import fancy styles. For IE only. NS4.x doesn't use the @import function */ + +@import url("/your.site/webbbs/themes/formIE.css"); + + + +/* END of blacknwhite.css */ + + + + + + + +/* Appendix.2-2: Example fancy styles CSS file + +Paste these into a text file and save as formIE.css */ + + + +/* Fancy form styles for IE */ + + + +input, textarea, select { + +border-top-width : 1px; + +border-right-width : 1px; + +border-bottom-width : 1px; + +border-left-width : 1px; + +} + + + +input { text-indent : 2px; } + + + +input.button { + +border-top-width : 1px; + +border-right-width : 1px; + +border-bottom-width : 1px; + +border-left-width : 1px; + +} + + + +.postbody { line-height: 18px} + +.magic { + margin-left: -20px; +} + +/* END of formIE.css */ diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test2.1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test2.1.css.out new file mode 100644 index 0000000..4874e68 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test2.1.css.out @@ -0,0 +1,173 @@ +*************** +start_document +*************** + +*************** +start_selector +s1[foo] +*************** + +*************** +property +prop1: 'String' +*************** + +*************** +end_selector +s1[foo] +*************** + +*************** +start_selector +s2[foo] +*************** + +*************** +start_selector +s3[foo="warning"] +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +s3[foo="warning"] +*************** + +*************** +start_selector +s4[foo~="warning"] +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +s4[foo~="warning"] +*************** + +*************** +start_selector +s5.warning +*************** + +*************** +property +prop1: value +*************** + +*************** +end_selector +s5.warning +*************** + +*************** +start_selector +E#myid +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +E#myid +*************** + +*************** +start_selector +S6:first-child +*************** + +*************** +property +prop1: value1 +*************** + +*************** +property +prop2: value2 +*************** + +*************** +end_selector +S6:first-child +*************** + +*************** +start_selector +S7:lang(c) +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +S7:lang(c) +*************** + +*************** +start_selector +S8+s2 +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +S8+s2 +*************** + +*************** +start_selector +.quotedstrings +*************** + +*************** +property +-test-string1: "foo'bar" +*************** + +*************** +property +-test-string2: "foo'bar" +*************** + +*************** +property +-test-string3: 'foo"bar' +*************** + +*************** +property +-test-string4: 'foo"bar' +*************** + +*************** +property +-test-string5: 'foo\\bar' +*************** + +*************** +end_selector +.quotedstrings +*************** + +*************** +end_document +*************** + diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test2.2.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test2.2.css.out new file mode 100644 index 0000000..f0d631a --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test2.2.css.out @@ -0,0 +1,3328 @@ +*************** +start_document +*************** + +*************** +start_selector +p.commentsbody +*************** + +*************** +property +border-left-style: solid +*************** + +*************** +property +border-width: 1px +*************** + +*************** +property +border-color: rgb(0, 0, 0) +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +margin-right: 20px +*************** + +*************** +property +text-align: justify +*************** + +*************** +end_selector +p.commentsbody +*************** + +*************** +start_selector +* +*************** + +*************** +property +font-family: Verdana, Arial, Helvetica, sans-serif, monospace +*************** + +*************** +end_selector +* +*************** + +*************** +start_selector +body +*************** + +*************** +property +background: #606060 +*************** + +*************** +property +color: #000000 +*************** + +*************** +end_selector +body +*************** + +*************** +start_selector +a:link +*************** + +*************** +property +color: #0000FF +*************** + +*************** +property +background: transparent +*************** + +*************** +property +text-decoration: none +*************** + +*************** +end_selector +a:link +*************** + +*************** +start_selector +a:visited +*************** + +*************** +property +color: #990099 +*************** + +*************** +property +background: transparent +*************** + +*************** +property +text-decoration: none +*************** + +*************** +end_selector +a:visited +*************** + +*************** +start_selector +a:active +*************** + +*************** +property +color: #000000 +*************** + +*************** +property +background: #ADD8E6 +*************** + +*************** +property +text-decoration: none +*************** + +*************** +end_selector +a:active +*************** + +*************** +start_selector +h1.rubrique_info +*************** + +*************** +property +color: #990033 +*************** + +*************** +property +margin: 0px 0px 0px 0px +*************** + +*************** +property +padding: 0em +*************** + +*************** +property +border: 0px +*************** + +*************** +property +font-size: 12px +*************** + +*************** +end_selector +h1.rubrique_info +*************** + +*************** +start_selector +h1.connexe +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +padding: 0em +*************** + +*************** +property +margin: 0px 0px 0px 0px +*************** + +*************** +property +color: #990033 +*************** + +*************** +end_selector +h1.connexe +*************** + +*************** +start_selector +a.rubrique_infolink +*************** + +*************** +property +text-decoration: none +*************** + +*************** +end_selector +a.rubrique_infolink +*************** + +*************** +start_selector +ul.rubrique_infoul +*************** + +*************** +property +display: inline +*************** + +*************** +property +list-style-type: square +*************** + +*************** +end_selector +ul.rubrique_infoul +*************** + +*************** +start_selector +ul.rubrique_infoul * +*************** + +*************** +property +width: 100% +*************** + +*************** +end_selector +ul.rubrique_infoul * +*************** + +*************** +start_selector +li.rubrique_infoul +*************** + +*************** +property +margin-left: 15px +*************** + +*************** +end_selector +li.rubrique_infoul +*************** + +*************** +start_selector +h1 +*************** + +*************** +property +color: #990033 +*************** + +*************** +end_selector +h1 +*************** + +*************** +start_selector +div.main +*************** + +*************** +property +background: white +*************** + +*************** +property +color: #000000 +*************** + +*************** +property +margin-left: 5px +*************** + +*************** +property +margin-right: 5px +*************** + +*************** +property +border: 1px black solid +*************** + +*************** +property +text-align: left +*************** + +*************** +property +font-size: 12px +*************** + +*************** +end_selector +div.main +*************** + +*************** +start_selector +div.lsfnbanner +*************** + +*************** +property +margin-left: 150px +*************** + +*************** +property +margin-right: 170px +*************** + +*************** +property +border-top: none +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +border-bottom: 1px black solid +*************** + +*************** +property +border-right: 1px black solid +*************** + +*************** +property +border-left: 1px black solid +*************** + +*************** +property +text-align: left +*************** + +*************** +property +font-size: 11px +*************** + +*************** +property +padding-top: 2px +*************** + +*************** +property +background-color: #eeeae6 +*************** + +*************** +end_selector +div.lsfnbanner +*************** + +*************** +start_selector +div.footer +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +property +padding-bottom: 3px +*************** + +*************** +property +border-top: 1px black solid +*************** + +*************** +property +border-left: 1px black solid +*************** + +*************** +property +border-right: 1px black solid +*************** + +*************** +property +text-align: left +*************** + +*************** +property +font-size: 9px +*************** + +*************** +property +background: #dcdff4 +*************** + +*************** +property +width: 600px +*************** + +*************** +property +margin-top: 40px +*************** + +*************** +property +margin-left: 20px +*************** + +*************** +end_selector +div.footer +*************** + +*************** +start_selector +div.footer p +*************** + +*************** +property +margin-left: 10px +*************** + +*************** +property +margin-top: 2px +*************** + +*************** +property +margin-bottom: 2px +*************** + +*************** +end_selector +div.footer p +*************** + +*************** +start_selector +a.lsfnlink:link, a.lsfnlink:visited, a.lsfnlink:active +*************** + +*************** +property +text-decoration: none +*************** + +*************** +property +color: #333333 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +end_selector +a.lsfnlink:link, a.lsfnlink:visited, a.lsfnlink:active +*************** + +*************** +start_selector +a.lsfnlink:hover +*************** + +*************** +property +text-decoration: underline +*************** + +*************** +property +color: black +*************** + +*************** +end_selector +a.lsfnlink:hover +*************** + +*************** +start_selector +div.menubartop +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-top: 0px +*************** + +*************** +property +font-size: 13px +*************** + +*************** +end_selector +div.menubartop +*************** + +*************** +start_selector +div.smallmenubar +*************** + +*************** +property +background: white +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-top: 0px +*************** + +*************** +property +padding-bottom: 0px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +text-align: right +*************** + +*************** +end_selector +div.smallmenubar +*************** + +*************** +start_selector +div.menuevent +*************** + +*************** +property +float: left +*************** + +*************** +property +width: 350px +*************** + +*************** +property +font-size: 11px +*************** + +*************** +property +text-align: left +*************** + +*************** +property +padding-top: 0px +*************** + +*************** +property +padding-bottom: 0px +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.menuevent +*************** + +*************** +start_selector +div.menubar +*************** + +*************** +property +background: #cac2a8 +*************** + +*************** +property +border-top: 1px black solid +*************** + +*************** +property +border-bottom: 1px black solid +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-top: 3px +*************** + +*************** +property +padding-bottom: 2px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 13px +*************** + +*************** +end_selector +div.menubar +*************** + +*************** +start_selector +div.menubar a +*************** + +*************** +property +text-decoration: none +*************** + +*************** +end_selector +div.menubar a +*************** + +*************** +start_selector +div.menudate +*************** + +*************** +property +float: left +*************** + +*************** +property +width: 130px +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +end_selector +div.menudate +*************** + +*************** +start_selector +div.menuaccroche +*************** + +*************** +property +margin-left: 30px +*************** + +*************** +property +float: left +*************** + +*************** +property +text-decoration: underline +*************** + +*************** +property +font-size: 14px +*************** + +*************** +end_selector +div.menuaccroche +*************** + +*************** +start_selector +div.menusearch +*************** + +*************** +property +float: right +*************** + +*************** +property +text-align: right +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +property +width: 170px +*************** + +*************** +end_selector +div.menusearch +*************** + +*************** +start_selector +div.menusearch p +*************** + +*************** +property +margin: 0px 0px 0px 0px +*************** + +*************** +end_selector +div.menusearch p +*************** + +*************** +start_selector +.searchinput +*************** + +*************** +property +border: solid 1px black +*************** + +*************** +end_selector +.searchinput +*************** + +*************** +start_selector +a#menulinkselect +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +end_selector +a#menulinkselect +*************** + +*************** +start_selector +div.leftbox +*************** + +*************** +property +width: 200px +*************** + +*************** +property +float: left +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +property +padding-right: 5px +*************** + +*************** +property +padding-bottom: 5px +*************** + +*************** +property +border-right: 1px black solid +*************** + +*************** +property +border-bottom: 1px black solid +*************** + +*************** +property +background: white +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +end_selector +div.leftbox +*************** + +*************** +start_selector +div.leftbox h1 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.leftbox h1 +*************** + +*************** +start_selector +div.leftbox h2 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.leftbox h2 +*************** + +*************** +start_selector +div.leftbox ul +*************** + +*************** +property +list-style-type: square +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +property +margin-left: 0em +*************** + +*************** +property +padding-left: 0em +*************** + +*************** +end_selector +div.leftbox ul +*************** + +*************** +start_selector +div.leftbox li +*************** + +*************** +property +margin-left: 10px +*************** + +*************** +end_selector +div.leftbox li +*************** + +*************** +start_selector +div.rightbox +*************** + +*************** +property +width: 150px +*************** + +*************** +property +float: right +*************** + +*************** +property +padding-top: 10px +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +property +padding-right: 15px +*************** + +*************** +property +padding-bottom: 5px +*************** + +*************** +property +border-left: 1px black solid +*************** + +*************** +property +border-bottom: 1px black solid +*************** + +*************** +property +text-align: left +*************** + +*************** +end_selector +div.rightbox +*************** + +*************** +start_selector +div.newjournaldiv +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +margin-left: 10% +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +width: 600px +*************** + +*************** +end_selector +div.newjournaldiv +*************** + +*************** +start_selector +div.newjournaldiv p +*************** + +*************** +property +margin-bottom: 0px +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +end_selector +div.newjournaldiv p +*************** + +*************** +start_selector +div.journaldiv +*************** + +*************** +property +margin-left: 0px +*************** + +*************** +property +margin-right: 0px +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +property +border: 1px black solid +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +property +padding-bottom: 5px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +background-color: #eef +*************** + +*************** +end_selector +div.journaldiv +*************** + +*************** +start_selector +div.journaldiv p +*************** + +*************** +property +margin-top: 10px +*************** + +*************** +property +margin-bottom: 0px +*************** + +*************** +end_selector +div.journaldiv p +*************** + +*************** +start_selector +div.journaldiv h1 +*************** + +*************** +property +color: #990033 +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.journaldiv h1 +*************** + +*************** +start_selector +div.journaldiv h2 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.journaldiv h2 +*************** + +*************** +start_selector +div.tipdiv +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +margin-right: 50px +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +background-color: #eee +*************** + +*************** +property +border: black solid 1px +*************** + +*************** +end_selector +div.tipdiv +*************** + +*************** +start_selector +div.tipdiv h1 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +color: black +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +end_selector +div.tipdiv h1 +*************** + +*************** +start_selector +div.tipdiv h2 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.tipdiv h2 +*************** + +*************** +start_selector +div.newsdiv +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +margin-right: 180px +*************** + +*************** +property +margin-top: 10px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +property +text-align: justify +*************** + +*************** +end_selector +div.newsdiv +*************** + +*************** +start_selector +div.newsdiv h1 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.newsdiv h1 +*************** + +*************** +start_selector +div.newsdiv h2 +*************** + +*************** +property +font-weight: normal +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.newsdiv h2 +*************** + +*************** +start_selector +div.newsdiv h3 +*************** + +*************** +property +font-weight: normal +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +end_selector +div.newsdiv h3 +*************** + +*************** +start_selector +div.objdiv +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +margin-right: 20px +*************** + +*************** +property +margin-top: 10px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +end_selector +div.objdiv +*************** + +*************** +start_selector +h1.newstitle +*************** + +*************** +property +text-align: left +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +margin: 0px 0px 0px 0px +*************** + +*************** +property +color: black +*************** + +*************** +end_selector +h1.newstitle +*************** + +*************** +start_selector +div.titlediv +*************** + +*************** +property +border-top: solid #cac2a8 2px +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +background-color: #eeeae6 +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +font-size: 11px +*************** + +*************** +end_selector +div.titlediv +*************** + +*************** +start_selector +div.bodydiv +*************** + +*************** +property +border: solid #9e9784 1px +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +padding-right: 10px +*************** + +*************** +property +padding-top: 10px +*************** + +*************** +property +padding-bottom: 5px +*************** + +*************** +property +margin-top: 2px +*************** + +*************** +property +text-align: justify +*************** + +*************** +end_selector +div.bodydiv +*************** + +*************** +start_selector +div.comments +*************** + +*************** +property +padding: 10px +*************** + +*************** +property +border-top: solid 2px #d37537 +*************** + +*************** +property +border-bottom: solid 2px #d37537 +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +property +background-color: #cacaca +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +line-height: 1.3em +*************** + +*************** +end_selector +div.comments +*************** + +*************** +start_selector +p.commentsbody +*************** + +*************** +property +border-left-style: solid +*************** + +*************** +property +border-width: 1px +*************** + +*************** +property +border-color: rgb(0, 0, 0) +*************** + +*************** +property +padding-left: 10px +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +margin-right: 20px +*************** + +*************** +end_selector +p.commentsbody +*************** + +*************** +start_selector +div.commentsreply +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +text-align: center +*************** + +*************** +property +margin-top: 50px +*************** + +*************** +end_selector +div.commentsreply +*************** + +*************** +start_selector +ul.commentsul +*************** + +*************** +property +list-style-type: none +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +property +margin-left: 1.25em +*************** + +*************** +property +padding-left: 0em +*************** + +*************** +property +border-left: 1px solid black +*************** + +*************** +end_selector +ul.commentsul +*************** + +*************** +start_selector +ul.commentsli +*************** + +*************** +property +margin: 10px +*************** + +*************** +end_selector +ul.commentsli +*************** + +*************** +start_selector +div.comments li +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +margin-left: 2px +*************** + +*************** +end_selector +div.comments li +*************** + +*************** +start_selector +div.comments h1 +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +color: black +*************** + +*************** +property +margin: 0px 20px 3px 0px +*************** + +*************** +property +background-color: rgb(226, 226, 226) +*************** + +*************** +property +padding-left: 1px +*************** + +*************** +property +font-weight: none +*************** + +*************** +end_selector +div.comments h1 +*************** + +*************** +start_selector +div.articlediv +*************** + +*************** +property +padding-left: 20px +*************** + +*************** +property +padding-right: 20px +*************** + +*************** +property +padding-top: 10px +*************** + +*************** +property +padding-bottom: 20px +*************** + +*************** +property +margin-right: 10px +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +border: solid 1px black +*************** + +*************** +property +margin-top: 10px +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +background-color: #E2E2E2 +*************** + +*************** +end_selector +div.articlediv +*************** + +*************** +start_selector +img +*************** + +*************** +property +border: 0px +*************** + +*************** +end_selector +img +*************** + +*************** +start_selector +div.sectionimg +*************** + +*************** +property +float: left +*************** + +*************** +property +margin-right: 10px +*************** + +*************** +property +margin-top: 5px +*************** + +*************** +end_selector +div.sectionimg +*************** + +*************** +start_selector +p.hautpage +*************** + +*************** +property +margin-top: 20px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +property +margin-left: 10px +*************** + +*************** +end_selector +p.hautpage +*************** + +*************** +start_selector +div.leftcol +*************** + +*************** +property +width: 202px +*************** + +*************** +property +width: 202px +*************** + +*************** +property +float: left +*************** + +*************** +property +padding: 0px +*************** + +*************** +end_selector +div.leftcol +*************** + +*************** +start_selector +div.logodiv +*************** + +*************** +property +border-right: 1px black solid +*************** + +*************** +property +border-bottom: 1px black solid +*************** + +*************** +property +padding: 0px +*************** + +*************** +property +line-height: 0px +*************** + +*************** +end_selector +div.logodiv +*************** + +*************** +start_selector +div.loginbox +*************** + +*************** +property +margin-left: 4px +*************** + +*************** +property +border: solid #a59f8b 1px +*************** + +*************** +property +margin-top: 2px +*************** + +*************** +property +padding: 5px +*************** + +*************** +property +background-color: #fff2e8 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +end_selector +div.loginbox +*************** + +*************** +start_selector +div.loginbox p +*************** + +*************** +property +margin: 0px +*************** + +*************** +property +padding: 0px +*************** + +*************** +end_selector +div.loginbox p +*************** + +*************** +start_selector +div.loginbox ul +*************** + +*************** +property +margin-left: 10px +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +margin-bottom: 0px +*************** + +*************** +property +padding: 0px +*************** + +*************** +property +list-style-type: none +*************** + +*************** +end_selector +div.loginbox ul +*************** + +*************** +start_selector +div.loginbox h1 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.loginbox h1 +*************** + +*************** +start_selector +div.loginbox h2 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.loginbox h2 +*************** + +*************** +start_selector +div.loginbox h3 +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +margin-bottom: 5px +*************** + +*************** +property +font-size: 12px +*************** + +*************** +end_selector +div.loginbox h3 +*************** + +*************** +start_selector +div.polldivtitle +*************** + +*************** +property +margin-bottom: 1px +*************** + +*************** +property +background-color: #cac2a8 +*************** + +*************** +property +margin-left: 4px +*************** + +*************** +property +margin-top: 15px +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +border-top: solid #a59f8b 1px +*************** + +*************** +property +border-bottom: solid #a59f8b 1px +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +end_selector +div.polldivtitle +*************** + +*************** +start_selector +div.polldiv +*************** + +*************** +property +margin-left: 4px +*************** + +*************** +property +border: 1px #a59f8b solid +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +padding: 5px +*************** + +*************** +property +background: #fff2e8 +*************** + +*************** +end_selector +div.polldiv +*************** + +*************** +start_selector +div.polldiv p +*************** + +*************** +property +margin: 5px +*************** + +*************** +property +padding: 0px +*************** + +*************** +end_selector +div.polldiv p +*************** + +*************** +start_selector +div.polldiv ul +*************** + +*************** +property +margin-left: 5px +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +property +padding: 0px +*************** + +*************** +property +list-style-type: none +*************** + +*************** +end_selector +div.polldiv ul +*************** + +*************** +start_selector +div.otherboxtitle +*************** + +*************** +property +margin-bottom: 2px +*************** + +*************** +property +background-color: #e3dabc +*************** + +*************** +property +margin-left: 4px +*************** + +*************** +property +margin-top: 15px +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +property +padding-top: 2px +*************** + +*************** +property +font-size: 11px +*************** + +*************** +property +border-top: solid #777364 1px +*************** + +*************** +property +border-bottom: solid #777364 1px +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +end_selector +div.otherboxtitle +*************** + +*************** +start_selector +div.otherbox +*************** + +*************** +property +margin-left: 4px +*************** + +*************** +property +border: 1px #a59f8b solid +*************** + +*************** +property +margin-top: 0px +*************** + +*************** +property +padding: 5px +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +background: #fff2e8 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +end_selector +div.otherbox +*************** + +*************** +start_selector +div.otherbox h1 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.otherbox h1 +*************** + +*************** +start_selector +div.otherbox h2 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 11px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.otherbox h2 +*************** + +*************** +start_selector +div.otherbox p +*************** + +*************** +property +margin-top: 5px +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +end_selector +div.otherbox p +*************** + +*************** +start_selector +div.rightlogo +*************** + +*************** +property +width: 90px +*************** + +*************** +property +float: right +*************** + +*************** +property +margin-right: 0px +*************** + +*************** +property +padding-top: 0px +*************** + +*************** +property +padding-left: 0px +*************** + +*************** +property +padding-bottom: 0px +*************** + +*************** +end_selector +div.rightlogo +*************** + +*************** +start_selector +div.centraldiv +*************** + +*************** +property +margin-left: 220px +*************** + +*************** +property +margin-right: 10px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +property +margin-top: 10px +*************** + +*************** +end_selector +div.centraldiv +*************** + +*************** +start_selector +div.centraldiv h1 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.centraldiv h1 +*************** + +*************** +start_selector +div.centraldiv h2 +*************** + +*************** +property +font-weight: normal +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.centraldiv h2 +*************** + +*************** +start_selector +div.centraldiv h3 +*************** + +*************** +property +font-weight: normal +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +end_selector +div.centraldiv h3 +*************** + +*************** +start_selector +div.centralinfo +*************** + +*************** +property +position: relative +*************** + +*************** +property +height: 160px +*************** + +*************** +end_selector +div.centralinfo +*************** + +*************** +start_selector +div.lefttopbox +*************** + +*************** +property +position: relative +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +property +padding-right: 5px +*************** + +*************** +property +padding-top: 5px +*************** + +*************** +property +border: 1px #a59f8b solid +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +background: #fff2e8 +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +width: 47% +*************** + +*************** +property +float: left +*************** + +*************** +end_selector +div.lefttopbox +*************** + +*************** +start_selector +div.lefttopbox p +*************** + +*************** +property +margin-top: 5px +*************** + +*************** +property +margin-bottom: 10px +*************** + +*************** +end_selector +div.lefttopbox p +*************** + +*************** +start_selector +div.lefttopbox h1 +*************** + +*************** +property +font-size: 13px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +margin: 0px +*************** + +*************** +property +text-align: right +*************** + +*************** +end_selector +div.lefttopbox h1 +*************** + +*************** +start_selector +div.lefttopbox h2 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.lefttopbox h2 +*************** + +*************** +start_selector +div.lefttopbox h3 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.lefttopbox h3 +*************** + +*************** +start_selector +div.righttopbox +*************** + +*************** +property +position: relative +*************** + +*************** +property +border: 1px #a59f8b solid +*************** + +*************** +property +background: white +*************** + +*************** +property +padding: 5px +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +width: 47% +*************** + +*************** +property +float: right +*************** + +*************** +end_selector +div.righttopbox +*************** + +*************** +start_selector +div.righttopbox h1 +*************** + +*************** +property +text-transform: uppercase +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +color: #ed7e00 +*************** + +*************** +property +font-size: 10px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.righttopbox h1 +*************** + +*************** +start_selector +div.righttopbox h2 +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +margin: 0px +*************** + +*************** +end_selector +div.righttopbox h2 +*************** + +*************** +start_selector +div.boardindex +*************** + +*************** +property +text-align: justify +*************** + +*************** +property +font-size: 11px +*************** + +*************** +property +padding: 10px +*************** + +*************** +property +margin-left: 20px +*************** + +*************** +property +margin-right: 20px +*************** + +*************** +end_selector +div.boardindex +*************** + +*************** +start_selector +a.boardindex:link, a.boardindex:visited, a.boardindex:active +*************** + +*************** +property +text-decoration: none +*************** + +*************** +property +color: red +*************** + +*************** +end_selector +a.boardindex:link, a.boardindex:visited, a.boardindex:active +*************** + +*************** +start_selector +div.boardleftmsg +*************** + +*************** +property +float: left +*************** + +*************** +property +margin-top: 3px +*************** + +*************** +end_selector +div.boardleftmsg +*************** + +*************** +start_selector +div.boardrightmsg +*************** + +*************** +property +margin-left: 130px +*************** + +*************** +property +margin-top: 3px +*************** + +*************** +property +padding-left: 5px +*************** + +*************** +end_selector +div.boardrightmsg +*************** + +*************** +start_selector +div.journalbody +*************** + +*************** +property +margin-left: 40px +*************** + +*************** +property +margin-top: 40px +*************** + +*************** +end_selector +div.journalbody +*************** + +*************** +start_selector +div.journalbody h1 +*************** + +*************** +property +font-size: 15px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +end_selector +div.journalbody h1 +*************** + +*************** +start_selector +div.journalbody p +*************** + +*************** +property +margin-bottom: 20px +*************** + +*************** +end_selector +div.journalbody p +*************** + +*************** +start_selector +.formulaire +*************** + +*************** +property +border: solid 1px black +*************** + +*************** +property +font-size: 12px +*************** + +*************** +property +background-color: #eef +*************** + +*************** +property +color: #000000 +*************** + +*************** +end_selector +.formulaire +*************** + +*************** +start_selector +.newcomments +*************** + +*************** +property +color: red +*************** + +*************** +property +font-weight: bold +*************** + +*************** +end_selector +.newcomments +*************** + +*************** +start_selector +div.commentsreplythanks +*************** + +*************** +property +margin-left: 100px +*************** + +*************** +property +margin-top: 50px +*************** + +*************** +property +margin-right: 100px +*************** + +*************** +property +background-color: #eee +*************** + +*************** +property +border: black solid 1px +*************** + +*************** +property +padding: 10px +*************** + +*************** +end_selector +div.commentsreplythanks +*************** + +*************** +start_selector +div.archivediv +*************** + +*************** +property +margin-right: 20px +*************** + +*************** +end_selector +div.archivediv +*************** + +*************** +start_selector +.archivedate +*************** + +*************** +property +color: #f30 +*************** + +*************** +end_selector +.archivedate +*************** + +*************** +start_selector +.archivelink +*************** + +*************** +property +font-size: 14px +*************** + +*************** +property +font-weight: bold +*************** + +*************** +property +text-decoration: underline +*************** + +*************** +end_selector +.archivelink +*************** + +*************** +end_document +*************** + diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test2.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test2.css.out new file mode 100644 index 0000000..f989353 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test2.css.out @@ -0,0 +1,63 @@ +*************** +start_document +*************** + +*************** +start_selector +S1 +*************** + +*************** +property +prop1: value1 +*************** + +*************** +end_selector +S1 +*************** + +*************** +start_selector +s1, s2 +*************** + +*************** +property +color: black +*************** + +*************** +property +background: white +*************** + +*************** +end_selector +s1, s2 +*************** + +*************** +start_selector +s1 s2, S3>s4 +*************** + +*************** +property +prop1: value1 +*************** + +*************** +property +prop2: value2 +*************** + +*************** +end_selector +s1 s2, S3>s4 +*************** + +*************** +end_document +*************** + diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test3.1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test3.1.css.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test3.1.css.out diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test3.2.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test3.2.css.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test3.2.css.out diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test3.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test3.css.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test3.css.out diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test4.1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test4.1.css.out new file mode 100644 index 0000000..95aa7b7 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test4.1.css.out @@ -0,0 +1,766 @@ +* { + font-family : Verdana, Arial, Helvetica, sans-serif, monospace !important +} + +tutu:class1:class2 { + test : ok +} + +body { + background : #606060; + color : #000000 +} + +a:link { + color : #0000FF; + background : transparent; + text-decoration : none +} + +a:visited { + color : #990099; + background : transparent; + text-decoration : none +} + +a:active { + color : #000000; + background : #ADD8E6; + text-decoration : none +} + +h1.rubrique_info { + color : #990033; + margin : 0px 0px 0px 0px; + padding : 0.4em; + border : 0px; + font-size : 12px +} + +h1.connexe { + font-size : 12px; + padding : 0.9em; + margin : 0px 0px 0px 0px; + color : #990033 +} + +a.rubrique_infolink { + text-decoration : none +} + +ul.rubrique_infoul { + display : inline; + list-style-type : square +} + +ul.rubrique_infoul * { + width : 100% +} + +li.rubrique_infoul { + margin-left : 15px +} + +h1 { + color : #990033 +} + +div.main { + background : white; + color : #000000; + margin-left : 5px; + margin-right : 5px; + border : 1px black solid; + text-align : left; + font-size : 12px +} + +div.lsfnbanner { + margin-left : 150px; + margin-right : 170px; + border-top : none; + padding-left : 10px; + padding-right : 10px; + border-bottom : 1px black solid; + border-right : 1px black solid; + border-left : 1px black solid; + text-align : left; + font-size : 11px; + padding-top : 2px; + background-color : #eeeae6 +} + +div.footer { + padding-top : 5px; + padding-bottom : 3px; + border-top : 1px black solid; + border-left : 1px black solid; + border-right : 1px black solid; + text-align : left; + font-size : 9px; + background : #dcdff4; + width : 600px; + margin-top : 40px; + margin-left : 20px +} + +div.footer p { + margin-left : 10px; + margin-top : 2px; + margin-bottom : 2px +} + +a.lsfnlink:link, a.lsfnlink:visited, a.lsfnlink:active { + text-decoration : none; + color : #333333; + font-size : 10px +} + +a.lsfnlink:hover { + text-decoration : underline; + color : black +} + +div.menubartop { + margin-bottom : 10px; + padding-left : 10px; + padding-right : 10px; + padding-top : 0px; + font-size : 13px +} + +div.smallmenubar { + background : white; + padding-left : 10px; + padding-right : 10px; + padding-top : 0px; + padding-bottom : 0px; + font-weight : bold; + font-size : 10px; + text-align : right +} + +div.menuevent { + float : left; + width : 350px; + font-size : 11px; + text-align : left; + padding-top : 0px; + padding-bottom : 0px; + padding-left : 10px; + font-weight : bold; + margin : 0px +} + +div.menubar { + background : #cac2a8; + border-top : 1px black solid; + border-bottom : 1px black solid; + padding-left : 10px; + padding-right : 10px; + padding-top : 3px; + padding-bottom : 2px; + font-weight : bold; + font-size : 13px +} + +div.menubar a { + text-decoration : none +} + +div.menudate { + float : left; + width : 130px; + padding-top : 5px +} + +div.menuaccroche { + margin-left : 30px; + float : left; + text-decoration : underline; + font-size : 14px +} + +div.menusearch { + float : right; + text-align : right; + padding-top : 5px; + width : 170px +} + +div.menusearch p { + margin : 0px 0px 0px 0px +} + +.searchinput { + border : solid 1px black +} + +a#menulinkselect { + color : #ed7e00 +} + +div.leftbox { + width : 200px; + float : left; + padding-left : 5px; + padding-right : 5px; + padding-bottom : 5px; + border-right : 1px black solid; + border-bottom : 1px black solid; + background : white; + margin-bottom : 10px +} + +div.leftbox h1 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 10px; + margin : 0px +} + +div.leftbox h2 { + font-weight : bold; + font-size : 12px; + margin : 0px +} + +div.leftbox ul { + list-style-type : square; + margin-bottom : 10px; + margin-left : 0.3em; + padding-left : 0.2em +} + +div.leftbox li { + margin-left : 10px +} + +div.rightbox { + width : 150px; + float : right; + padding-top : 10px; + padding-left : 5px; + padding-right : 15px; + padding-bottom : 5px; + border-left : 1px black solid; + border-bottom : 1px black solid; + text-align : left +} + +div.newjournaldiv { + text-align : justify; + margin-left : 10%; + font-size : 12px; + width : 600px +} + +div.newjournaldiv p { + margin-bottom : 0px; + margin-top : 20px +} + +div.journaldiv { + margin-left : 0px; + margin-right : 0px; + margin-top : 20px; + margin-bottom : 20px; + border : 1px black solid; + padding-top : 5px; + padding-bottom : 5px; + padding-right : 10px; + padding-left : 10px; + background-color : #eef +} + +div.journaldiv p { + margin-top : 10px; + margin-bottom : 0px +} + +div.journaldiv h1 { + color : #990033; + font-size : 14px; + margin : 0px +} + +div.journaldiv h2 { + font-size : 10px; + margin : 0px +} + +div.tipdiv { + margin-left : 220px; + margin-right : 50px; + margin-top : 20px; + padding-top : 5px; + padding-right : 10px; + padding-left : 10px; + text-align : justify; + background-color : #eee; + border : black solid 1px +} + +div.tipdiv h1 { + font-weight : bold; + font-size : 14px; + color : black; + margin-top : 0px; + margin-bottom : 20px +} + +div.tipdiv h2 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 12px; + margin : 0px +} + +div.newsdiv { + margin-left : 220px; + margin-right : 180px; + margin-top : 10px; + margin-bottom : 20px; + text-align : justify +} + +div.newsdiv h1 { + font-weight : bold; + font-size : 14px; + margin : 0px +} + +div.newsdiv h2 { + font-weight : normal; + font-size : 12px; + margin : 0px +} + +div.newsdiv h3 { + font-weight : normal; + font-size : 12px; + margin-bottom : 20px +} + +div.objdiv { + margin-left : 220px; + margin-right : 20px; + margin-top : 10px; + margin-bottom : 20px +} + +h1.newstitle { + text-align : left; + font-size : 14px; + margin : 0px 0px 0px 0px; + color : black +} + +div.titlediv { + border-top : solid #cac2a8 2px; + margin-top : 20px; + background-color : #eeeae6; + padding-left : 10px; + font-size : 11px +} + +div.bodydiv { + border : solid #9e9784 1px; + padding-left : 10px; + padding-right : 10px; + padding-top : 10px; + padding-bottom : 5px; + margin-top : 2px; + text-align : justify +} + +div.comments { + padding : 10px; + border-top : solid 2px #d37537; + border-bottom : solid 2px #d37537; + margin-top : 20px; + margin-bottom : 10px; + background-color : #cacaca; + font-size : 12px; + line-height : 1.3em +} + +p.commentsbody { + border-left-style : solid; + border-width : 1px; + border-color : rgb(0, 0, 0); + padding-left : 10px; + text-align : justify; + margin-right : 20px +} + +div.commentsreply { + margin-left : 220px; + text-align : center; + margin-top : 50px +} + +ul.commentsul { + list-style-type : none; + margin-bottom : 10px; + margin-left : 1.25em; + padding-left : 0em; + border-left : 1px solid black +} + +ul.commentsli { + margin : 10px +} + +div.comments li { + margin-top : 20px; + margin-left : 2px +} + +div.comments h1 { + font-size : 12px; + color : black; + margin : 0px 20px 3px 0px; + background-color : rgb(226, 226, 226); + padding-left : 1px; + font-weight : none +} + +div.articlediv { + padding-left : 20px; + padding-right : 20px; + padding-top : 10px; + padding-bottom : 20px; + margin-right : 10px; + margin-left : 220px; + border : solid 1px black; + margin-top : 10px; + text-align : justify; + background-color : #E2E2E2 +} + +img { + border : 0px +} + +div.sectionimg { + float : left; + margin-right : 10px; + margin-top : 5px +} + +p.hautpage { + margin-top : 20px; + margin-bottom : 20px; + margin-left : 10px +} + +div.leftcol { + width : 202px; + width : 202px; + float : left; + padding : 0px +} + +div.logodiv { + border-right : 1px black solid; + border-bottom : 1px black solid; + padding : 0px; + line-height : 0px +} + +div.loginbox { + margin-left : 4px; + border : solid #a59f8b 1px; + margin-top : 2px; + padding : 5px; + background-color : #fff2e8; + font-size : 10px +} + +div.loginbox p { + margin : 0px; + padding : 0px +} + +div.loginbox ul { + margin-left : 10px; + margin-top : 0px; + margin-bottom : 0px; + padding : 0px; + list-style-type : none +} + +div.loginbox h1 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 10px; + margin : 0px +} + +div.loginbox h2 { + font-weight : bold; + font-size : 12px; + margin : 0px +} + +div.loginbox h3 { + margin-top : 0px; + margin-bottom : 5px; + font-size : 12px +} + +div.polldivtitle { + margin-bottom : 1px; + background-color : #cac2a8; + margin-left : 4px; + margin-top : 15px; + padding-left : 5px; + font-size : 10px; + border-top : solid #a59f8b 1px; + border-bottom : solid #a59f8b 1px; + text-transform : uppercase +} + +div.polldiv { + margin-left : 4px; + border : 1px #a59f8b solid; + margin-top : 0px; + padding : 5px; + background : #fff2e8 +} + +div.polldiv p { + margin : 5px; + padding : 0px +} + +div.polldiv ul { + margin-left : 5px; + margin-top : 0px; + margin-bottom : 10px; + padding : 0px; + list-style-type : none +} + +div.otherboxtitle { + margin-bottom : 2px; + background-color : #e3dabc; + margin-left : 4px; + margin-top : 15px; + padding-left : 5px; + padding-top : 2px; + font-size : 11px; + border-top : solid #777364 1px; + border-bottom : solid #777364 1px; + text-transform : uppercase; + font-weight : bold +} + +div.otherbox { + margin-left : 4px; + border : 1px #a59f8b solid; + margin-top : 0px; + padding : 5px; + text-align : justify; + background : #fff2e8; + font-size : 10px +} + +div.otherbox h1 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 10px; + margin : 0px +} + +div.otherbox h2 { + font-weight : bold; + font-size : 11px; + margin : 0px +} + +div.otherbox p { + margin-top : 5px; + margin-bottom : 10px +} + +div.rightlogo { + width : 90px; + float : right; + margin-right : 0px; + padding-top : 0px; + padding-left : 0px; + padding-bottom : 0px +} + +div.centraldiv { + margin-left : 220px; + margin-right : 10px; + margin-bottom : 20px; + margin-top : 10px +} + +div.centraldiv h1 { + font-weight : bold; + font-size : 14px; + margin : 0px +} + +div.centraldiv h2 { + font-weight : normal; + font-size : 12px; + margin : 0px +} + +div.centraldiv h3 { + font-weight : normal; + font-size : 12px; + margin-bottom : 20px +} + +div.centralinfo { + position : relative; + height : 160px +} + +div.lefttopbox { + position : relative; + padding-left : 5px; + padding-right : 5px; + padding-top : 5px; + border : 1px #a59f8b solid; + text-align : justify; + background : #fff2e8; + font-size : 12px; + width : 47%; + float : left +} + +div.lefttopbox p { + margin-top : 5px; + margin-bottom : 10px +} + +div.lefttopbox h1 { + font-size : 13px; + font-weight : bold; + margin : 0px; + text-align : right +} + +div.lefttopbox h2 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 10px; + margin : 0px +} + +div.lefttopbox h3 { + font-weight : bold; + font-size : 12px; + margin : 0px +} + +div.righttopbox { + position : relative; + border : 1px #a59f8b solid; + background : white; + padding : 5px; + text-align : justify; + font-size : 12px; + width : 47%; + float : right +} + +div.righttopbox h1 { + text-transform : uppercase; + font-weight : bold; + color : #ed7e00; + font-size : 10px; + margin : 0px +} + +div.righttopbox h2 { + font-weight : bold; + font-size : 12px; + margin : 0px +} + +div.boardindex { + text-align : justify; + font-size : 11px; + padding : 10px; + margin-left : 20px; + margin-right : 20px +} + +a.boardindex:link, a.boardindex:visited, a.boardindex:active { + text-decoration : none; + color : red +} + +div.boardleftmsg { + float : left; + margin-top : 3px +} + +div.boardrightmsg { + margin-left : 130px; + margin-top : 3px; + padding-left : 5px +} + +div.journalbody { + margin-left : 40px; + margin-top : 40px +} + +div.journalbody h1 { + font-size : 15px; + font-weight : bold +} + +div.journalbody p { + margin-bottom : 20px +} + +.formulaire { + border : solid 1px black; + font-size : 12px; + background-color : #eef; + color : #000000 +} + +.newcomments { + color : red; + font-weight : bold +} + +div.commentsreplythanks { + margin-left : 100px; + margin-top : 50px; + margin-right : 100px; + background-color : #eee; + border : black solid 1px; + padding : 10px +} + +div.archivediv { + margin-right : 20px +} + +.archivedate { + color : #f30 +} + +.archivelink { + font-size : 14px; + font-weight : bold; + text-decoration : underline +}
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test4.2.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test4.2.css.out new file mode 100644 index 0000000..b67ae23 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test4.2.css.out @@ -0,0 +1,24 @@ +@charset "ISO-8859-1" ; + +@import url("http://www.yahoo.com/css")print, screen ; + +@font-face { + font-family : 'Robson Celtic'; + src : url(http://site/fonts/rob-celt) +} + +@page left :one-two { + margin : 10pt; + border : none +} + + +@media print, screen, projection { + H1 { + font-family : 'Robson Celtic', serif + } + P { + background : black; + foreground : white + } +}
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test5.1.css.out b/src/3rdparty/libcroco/tests/test-output-refs/test5.1.css.out new file mode 100644 index 0000000..2f0bc54 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test5.1.css.out @@ -0,0 +1,105 @@ +''''''''''''''''''''''''' +xml start element: document + + :first-child { + first-child-prop : first-child-value + } + +xml end element: document +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E0 + + :first-child { + first-child-prop : first-child-value + } + E0 { + prop0 : val0 + } + +xml end element: E0 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E1 + + E0+E1 { + pro1 : val1 + } + +xml end element: E1 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E1-1 + + :first-child { + first-child-prop : first-child-value + } + E1 E1-1 { + prop2 : val2 + } + E1>E1-1 { + prop3 : val3 + } + document E1-1 { + prop4 : val4 + } + +xml end element: E1-1 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E2 + + [attr2="val2"] { + prop5 : val5 + } + E2[attr2="val2"] { + prop8 : val8 + } + +xml end element: E2 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E3 + + [attr3~="val3_2"] { + prop6 : val6 + } + +xml end element: E3 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E4 + + [attr4|="val4"] { + prop7 : val7 + } + +xml end element: E4 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E5 + + .class5 { + prop8 : val8 + } + +xml end element: E5 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E6 + + #id6 { + prop9 : val9 + } + +xml end element: E6 +''''''''''''''''''''''''' +''''''''''''''''''''''''' +xml start element: E7 + + :lang(fr) { + lang-prop : lang-value + } + +xml end element: E7 +''''''''''''''''''''''''' diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test6.out b/src/3rdparty/libcroco/tests/test-output-refs/test6.out new file mode 100644 index 0000000..cdc81db --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test6.out @@ -0,0 +1,8 @@ +.str0 { + stroke : #007844; + stroke-width : 44 +} + +.fil0 { + fill : url(#id0) +}
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test7.out b/src/3rdparty/libcroco/tests/test-output-refs/test7.out new file mode 100644 index 0000000..21d10d7 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test7.out @@ -0,0 +1,43 @@ +.exp1n1 { + stroke-width : 4000000 +} + +.exp1n2 { + stroke-width : 4000000 +} + +.exp1n3 { + stroke-width : 4000000 +} + +.exp2n1 { + stroke-width : 0.000004 +} + +.exp2n2 { + stroke-width : 0.000004 +} + +.exp3n1 { + stroke-width : 4000000em +} + +.exp3n2 { + stroke-width : 4000000ex +} + +.exp3n3 { + stroke-width : 4000000in +} + +.exp4n1 { + stroke-width : 31400 +} + +.exp4n2 { + stroke-width : 0.000314 +} + +.e4n2 { + stroke-width : 0.000024 +} diff --git a/src/3rdparty/libcroco/tests/test-output-refs/test8.out b/src/3rdparty/libcroco/tests/test-output-refs/test8.out new file mode 100644 index 0000000..9e25188 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-output-refs/test8.out @@ -0,0 +1,15 @@ +**************** +Parsing 'foo' +foo +**************** +Parsing 'foo,bar' +foo, bar +**************** +Parsing 'foo , bar ' +foo, bar +**************** +Parsing 'foo > bar' +foo>bar +**************** +Parsing '.foo .bar' +.foo.bar diff --git a/src/3rdparty/libcroco/tests/test-parsing-location.sh b/src/3rdparty/libcroco/tests/test-parsing-location.sh new file mode 100755 index 0000000..4d7af34 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-parsing-location.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT --dump-location $TEST_INPUTS_DIR/parsing-location.css diff --git a/src/3rdparty/libcroco/tests/test-prop-ident.sh b/src/3rdparty/libcroco/tests/test-prop-ident.sh new file mode 100755 index 0000000..31e6127 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-prop-ident.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT "$TEST_INPUTS_DIR"/prop-vendor-ident.css diff --git a/src/3rdparty/libcroco/tests/test-sel-child-class.sh b/src/3rdparty/libcroco/tests/test-sel-child-class.sh new file mode 100755 index 0000000..ebfbb96 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-sel-child-class.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT -e --user-sheet $TEST_INPUTS_DIR/sel-child-class.css --xml $TEST_INPUTS_DIR/sel-child-class.xml --xpath /test/body/div/div/p diff --git a/src/3rdparty/libcroco/tests/test-several-media.sh b/src/3rdparty/libcroco/tests/test-several-media.sh new file mode 100755 index 0000000..c0a0c9d --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-several-media.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT "$TEST_INPUTS_DIR"/several-media.css diff --git a/src/3rdparty/libcroco/tests/test-unknown-at-rule.sh b/src/3rdparty/libcroco/tests/test-unknown-at-rule.sh new file mode 100755 index 0000000..08ceff6 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-unknown-at-rule.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT "$TEST_INPUTS_DIR"/unknown-at-rule.css diff --git a/src/3rdparty/libcroco/tests/test-unknown-at-rule2.sh b/src/3rdparty/libcroco/tests/test-unknown-at-rule2.sh new file mode 100755 index 0000000..fe58731 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test-unknown-at-rule2.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +test -z "$CSSLINT" && . ./global-test-vars.sh + +$CSSLINT "$TEST_INPUTS_DIR"/unknown-at-rule2.css diff --git a/src/3rdparty/libcroco/tests/test0-main.c b/src/3rdparty/libcroco/tests/test0-main.c new file mode 100644 index 0000000..993c983 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test0-main.c @@ -0,0 +1,203 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +#include <stdio.h> +#include "cr-input.h" +#include "string.h" + +/** + *@file + *Some test facilities for the #CRInput class. + */ + +/** + *The options data structure. + *The variable of this data structure are set + *during the parsing the command line by the + *parse_command_line() function. + */ +struct Options { + gboolean display_help; + gboolean display_about; + gchar **files_list; +}; + +static void + display_help (char *prg_name); + +static void + display_about (char *prg_name); + +static void + parse_command_line (int a_argc, char **a_argv, struct Options *a_options); + +static enum CRStatus + test_cr_input_read_byte (guchar * a_file_uri); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + g_print ("\n\n"); + g_print ("usage: %s <file-to-parse>\n", prg_name); + g_print ("\t <file-to-parse>: the file to parse\n"); + g_print ("\n\n"); + g_print ("This test just reads the file byte per byte\nand sends each byte to stdout\n"); + g_print ("\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + g_print ("\n\n"); + g_print ("%s is a libcroco CRInput class test program.\n", prg_name); + g_print ("It should run on GNU compliants systems.\n"); + g_print ("\n\n"); + g_print ("Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + g_print ("\n\n"); +} + +/** + *Parses the command line and updates an abstract "options" data structure. + *@param a_argc the argc variable passed to the main function by the OS. + *@param a_argv the argv variable passed to the main function by the OS. + *@param a_options out parameter. The abstraction of the parsed the options. + */ +static void +parse_command_line (int a_argc, char **a_argv, struct Options *a_options) +{ + int i = 0; + + g_return_if_fail (a_options); + + memset (a_options, 0, sizeof (struct Options)); + + for (i = 1; i < a_argc; i++) { + if (a_argv[i][0] != '-') + break; + + if (!strcmp (a_argv[i], "-h") + || !strcmp (a_argv[i], "--help")) { + a_options->display_help = TRUE; + } + if (!strcmp (a_argv[i], "--about")) { + a_options->display_about = TRUE; + } + } + + if (i >= a_argc) { + /*No file parameter where given */ + a_options->files_list = NULL; + } else { + a_options->files_list = &a_argv[i]; + } +} + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_input_read_byte (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CRInput *input = NULL; + guchar byte = 0; + guint c = 0; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + input = cr_input_new_from_uri ((const gchar *) a_file_uri, CR_UTF_8); + + if (!input) { + cr_utils_trace_debug ("Input Stream creation failed."); + return CR_ERROR; + } + + for (status = CR_OK; status == CR_OK;) { + status = cr_input_read_byte (input, &byte); + + if (status == CR_OK) { + c = byte; + printf ("%d", c); + fflush (stdout); + } + } + + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + } + + cr_input_destroy (input); + input = NULL; + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + + parse_command_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + test_cr_input_read_byte ((guchar *) options.files_list[0]); + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test1-main.c b/src/3rdparty/libcroco/tests/test1-main.c new file mode 100644 index 0000000..1c5f127 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test1-main.c @@ -0,0 +1,197 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information + */ + +#include <stdio.h> +#include "cr-input.h" +#include "string.h" + +/** + *@file + *Some test facilities for the #CRInput class. + */ + +/** + *The options data structure. + *The variable of this data structure are set + *during the parsing the command line by the + *parse_command_line() function. + */ +struct Options { + gboolean display_help; + gboolean display_about; + gchar **files_list; +}; + +static void + display_help (char *prg_name); + +static void + display_about (char *prg_name); + +static void + parse_command_line (int a_argc, char **a_argv, struct Options *a_options); + +static enum CRStatus + test_cr_input_read_char (guchar * a_file_uri); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + g_print ("\n\n"); + g_print ("usage: %s <file-to-parse>\n", prg_name); + g_print ("\t <file-to-parse>: the file to parse\n"); + g_print ("\n\n"); + g_print ("This test just reads the file character per character\nand sends each character to stdout\n"); + g_print ("\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + g_print ("\n\n"); + g_print ("%s is a libcroco CRInput class test program.\n", prg_name); + g_print ("It should run on GNU compliants systems.\n"); + g_print ("\n\n"); + g_print ("Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + g_print ("\n\n"); +} + +/** + *Parses the command line and updates an abstract "options" data structure. + *@param a_argc the argc variable passed to the main function by the OS. + *@param a_argv the argv variable passed to the main function by the OS. + *@param a_options out parameter. The abstraction of the parsed the options. + */ +static void +parse_command_line (int a_argc, char **a_argv, struct Options *a_options) +{ + int i = 0; + + g_return_if_fail (a_options); + + memset (a_options, 0, sizeof (struct Options)); + + for (i = 1; i < a_argc; i++) { + if (a_argv[i][0] != '-') + break; + + if (!strcmp (a_argv[i], "-h") + || !strcmp (a_argv[i], "--help")) { + a_options->display_help = TRUE; + } + if (!strcmp (a_argv[i], "--about")) { + a_options->display_about = TRUE; + } + } + + if (i >= a_argc) { + /*No file parameter where given */ + a_options->files_list = NULL; + } else { + a_options->files_list = &a_argv[i]; + } +} + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +enum CRStatus +test_cr_input_read_char (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CRInput *input = NULL; + guint32 c = 0; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + input = cr_input_new_from_uri ((const gchar *) a_file_uri, CR_UTF_8); + + if (!input) { + cr_utils_trace_debug ("Input Stream creation failed."); + return CR_ERROR; + } + + for (status = CR_OK; status == CR_OK;) { + status = cr_input_read_char (input, &c); + + if (status == CR_OK) { + printf ("%c", c); + fflush (stdout); + } + } + + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + } + + cr_input_destroy (input); + input = NULL; + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + + parse_command_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + test_cr_input_read_char ((guchar *) options.files_list[0]); + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test2-main.c b/src/3rdparty/libcroco/tests/test2-main.c new file mode 100644 index 0000000..5268ed3 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test2-main.c @@ -0,0 +1,564 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms + * of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +#include <stdio.h> +#include <string.h> +#include "cr-test-utils.h" +#include "cr-parser.h" + +/** + *@file + *Some test facilities for the #CRParser class. + */ + +CRDocHandler *gv_test_handler = { 0 }; + +static void + display_help (char *prg_name); + +static void + display_about (char *prg_name); + +static enum CRStatus + test_cr_parser_parse (guchar * a_file_uri); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + fprintf (stdout, "\n\n"); + fprintf (stdout, "usage: %s <file-to-parse>\n", prg_name); + fprintf (stdout, "\t <file-to-parse>: the file to parse\n"); + fprintf (stdout, "\n\n"); + fprintf (stdout, "Tests the cr_parser_parse () method.\n"); + fprintf (stdout, "Returns OK if the status is CR_OK, KO otherwise\n"); + fprintf (stdout, "\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + fprintf (stdout, "\n\n"); + fprintf (stdout, "%s is a libcroco CRParser class test program.\n", + prg_name); + fprintf (stdout, "It should run on GNU compliants systems.\n"); + fprintf (stdout, "\n\n"); + fprintf (stdout, + "Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + fprintf (stdout, "\n\n"); +} + +/*************************** + *Some SAC document handlers + *for TEST PURPOSES. + ***************************/ + +static void +test_start_document (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_document\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_document (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_document\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_import_style (CRDocHandler * a_handler, + GList * a_media_list, + CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location) +{ + (void) a_uri; + + g_return_if_fail (a_handler) ; + + fprintf (stdout, "****************\n"); + fprintf (stdout, "import_style\n"); + + if (a_media_list) { + GList *cur = NULL; + + fprintf (stdout, "\nmedia list:\n"); + fprintf (stdout, "-------------\n"); + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data) { + gchar *str = + g_strndup + (((CRString *) cur->data)->stryng->str, + ((CRString *) cur->data)->stryng->len); + + if (str) { + fprintf (stdout, "%s\n", str); + g_free (str); + str = NULL; + } + } + } + + fprintf (stdout, "\ndefault namespace:\n"); + fprintf (stdout, "--------------------\n"); + + if (a_uri_default_ns) { + guchar *str = (guchar *) cr_string_dup2 + (a_uri_default_ns) ; + if (str) { + fprintf (stdout, "%s\n", str); + g_free (str); + str = NULL; + } + } + } + + fprintf (stdout, "******************\n\n"); + a_uri = NULL; /*keep compiler happy */ +} + +static void +test_namespace_declaration (CRDocHandler * a_handler, + CRString * a_prefix, + CRString * a_uri, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "namespace_declaration:\n"); + + if (a_prefix) { + gchar *prefix = NULL; + + prefix = cr_string_dup2 (a_prefix) ; + if (prefix) { + fprintf (stdout, "prefix: %s\n", prefix); + g_free (prefix); + prefix = NULL; + } + } + if (a_uri) { + gchar *uri = NULL; + + uri = cr_string_dup2 (a_uri) ; + if (uri) { + fprintf (stdout, "uri: %s\n", uri); + g_free (uri); + uri = NULL; + } + } + fprintf (stdout, "\n"); + + fprintf (stdout, "***************\n\n"); + +} + +static void +test_comment (CRDocHandler * a_handler, + CRString * a_comment) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "comment:\n"); + if (a_comment) { + gchar *comment = NULL; + + comment = cr_string_dup2 (a_comment); + + if (comment) { + fprintf (stdout, "\n/*----------------------\n"); + fprintf (stdout, "%s\n", comment); + fprintf (stdout, "-------------------------*/\n"); + g_free (comment); + comment = NULL; + } + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_selector (CRDocHandler * a_handler, + CRSelector * a_selector_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_selector\n"); + + if (a_selector_list) { + cr_selector_dump (a_selector_list, stdout); + fprintf (stdout, "\n"); + } + + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_selector (CRDocHandler * a_handler, + CRSelector * a_selector_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_selector\n"); + + if (a_selector_list) { + cr_selector_dump (a_selector_list, stdout); + fprintf (stdout, "\n"); + } + + fprintf (stdout, "***************\n\n"); +} + +static void +test_property (CRDocHandler * a_handler, + CRString * a_name, + CRTerm * a_expr, + gboolean a_important) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "property\n"); + + if (a_name + && a_name->stryng + && a_name->stryng->str) { + gchar *name = g_strndup + (a_name->stryng->str, + a_name->stryng->len); + + if (name) { + fprintf (stdout, "%s", name); + } + if (a_expr) { + fprintf (stdout, ": "); + cr_term_dump (a_expr, stdout); + } + if (name) { + g_free (name); + name = NULL; + } + fprintf (stdout, "\n"); + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_font_face (CRDocHandler * a_handler, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_font_face\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_font_face (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_font_face\n"); + fprintf (stdout, "***************\n\n"); + +} + +static void +test_start_media (CRDocHandler * a_handler, + GList * a_media_list, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_media\n"); + + if (a_media_list) { + GList *cur = NULL; + gchar *medium = NULL; + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data == NULL) + continue; + medium = cr_string_dup2 + ((CRString *) cur->data); + if (medium == NULL) + continue; + fprintf (stdout, "medium: %s\n", medium); + if (medium) { + g_free (medium); + medium = NULL; + } + } + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_media (CRDocHandler * a_handler, + GList * a_media_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_media\n"); + + if (a_media_list) { + GList *cur = NULL; + gchar *medium = NULL; + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data == NULL) + continue; + + medium = g_strndup (((CRString *) cur->data)->stryng->str, + ((CRString *) cur->data)->stryng->len); + if (medium == NULL) + continue; + fprintf (stdout, "medium: %s\n", medium); + if (medium) { + g_free (medium); + medium = NULL; + } + } + } + + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_page (CRDocHandler * a_handler, + CRString * a_name, + CRString * a_pseudo_page, + CRParsingLocation *a_location) +{ + gchar *name = NULL, + *pseudo_page = NULL; + + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_page\n"); + + if (a_name) { + name = cr_string_dup2 (a_name) ; + } + if (a_pseudo_page) { + pseudo_page = cr_string_dup2 (a_pseudo_page); + } + if (name) { + fprintf (stdout, "%s", name); + } + if (pseudo_page) { + fprintf (stdout, ": %s\n", pseudo_page); + } + fprintf (stdout, "***************\n\n"); + if (name) { + g_free (name); + name = NULL; + } + if (pseudo_page) { + g_free (pseudo_page); + pseudo_page = NULL; + } +} + +static void +test_end_page (CRDocHandler * a_handler, + CRString * a_name, + CRString * a_pseudo_page) +{ + gchar *name = NULL, + *pseudo_page = NULL; + + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_page\n"); + + if (a_name) { + name = cr_string_dup2 (a_name) ; + } + if (a_pseudo_page) { + pseudo_page = cr_string_dup2 (a_pseudo_page) ; + } + if (name) { + fprintf (stdout, "%s", name); + } + if (pseudo_page) { + fprintf (stdout, ": %s\n", pseudo_page); + + } + fprintf (stdout, "***************\n\n"); + if (name) { + g_free (name); + name = NULL; + } + if (pseudo_page) { + g_free (pseudo_page); + pseudo_page = NULL; + } +} + +static void +test_ignorable_at_rule (CRDocHandler * a_handler, + CRString * a_name) +{ + gchar *name = NULL; + + g_return_if_fail (a_handler); + + fprintf (stdout, "*********************\n"); + fprintf (stdout, "ignorable_at_rule\n"); + + if (a_name) { + name = cr_string_dup2 (a_name); + } + if (name) { + fprintf (stdout, "%s\n", name); + } + fprintf (stdout, "*********************\n\n"); +} + +static void +init_test_sac_handler (CRDocHandler * a_handler) +{ + a_handler->start_document = test_start_document; + a_handler->end_document = test_end_document; + a_handler->import_style = test_import_style; + a_handler->namespace_declaration = test_namespace_declaration; + a_handler->comment = test_comment; + a_handler->start_selector = test_start_selector; + a_handler->end_selector = test_end_selector; + a_handler->property = test_property; + a_handler->start_font_face = test_start_font_face; + a_handler->end_font_face = test_end_font_face; + a_handler->start_media = test_start_media; + a_handler->end_media = test_end_media; + a_handler->start_page = test_start_page; + a_handler->end_page = test_end_page; + a_handler->ignorable_at_rule = test_ignorable_at_rule; +} + +/*************************** + *END of TEST SAC document + *handlers. + ***************************/ + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_parser_parse (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + gv_test_handler = cr_doc_handler_new (); + init_test_sac_handler (gv_test_handler); + + parser = cr_parser_new (NULL); + + status = cr_parser_set_sac_handler (parser, gv_test_handler); + + if (status != CR_OK) { + cr_parser_destroy (parser); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + } + + status = cr_parser_parse_file (parser, a_file_uri, CR_ASCII); + + cr_parser_destroy (parser); + + gv_test_handler = NULL; + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + enum CRStatus status = CR_OK; + + cr_test_utils_parse_cmd_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + status = test_cr_parser_parse ((guchar *) options.files_list[0]); + + if (status != CR_OK) { + fprintf (stdout, "KO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test3-main.c b/src/3rdparty/libcroco/tests/test3-main.c new file mode 100644 index 0000000..1979778 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test3-main.c @@ -0,0 +1,545 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include <stdio.h> +#include <string.h> +#include "cr-test-utils.h" +#include "cr-parser.h" + +/** + *@file + *Some test facilities for the #CRParser class. + */ + +CRDocHandler *gv_test_handler = { 0 }; + +static void display_help (char *prg_name); + +static void display_about (char *prg_name); + +static enum CRStatus test_cr_parser_parse (guchar * a_file_uri); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + fprintf (stdout, "\n\n"); + fprintf (stdout, "usage: %s <file-to-parse>\n", prg_name); + fprintf (stdout, "\t <file-to-parse>: the file to parse\n"); + fprintf (stdout, "\n\n"); + fprintf (stdout, "Tests the cr_parser_parse () method.\n"); + fprintf (stdout, "Tests the parsing following the css core syntax\n"); + fprintf (stdout, "Returns OK if the status is CR_OK, KO otherwise\n"); + fprintf (stdout, "\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + fprintf (stdout, "\n\n"); + fprintf (stdout, "%s is a libcroco CRParser class test program.\n", + prg_name); + fprintf (stdout, "It should run on GNU compliants systems.\n"); + fprintf (stdout, "\n\n"); + fprintf (stdout, + "Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + fprintf (stdout, "\n\n"); +} + +/*************************** + *Some SAC document handlers + *for TEST PURPOSES. + ***************************/ + +static void +test_start_document (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_document\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_document (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_document\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_import_style (CRDocHandler * a_handler, + GList * a_media_list, CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + (void) a_uri; + + fprintf (stdout, "****************\n"); + fprintf (stdout, "import_style\n"); + + if (a_media_list) { + GList *cur = NULL; + + fprintf (stdout, "\nmedia list:\n"); + fprintf (stdout, "-------------\n"); + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data) { + gchar *str = + cr_string_dup2 ((CRString *) cur->data); + if (str) { + fprintf (stdout, "%s\n", str); + g_free (str); + str = NULL; + } + } + } + fprintf (stdout, "\ndefault namespace:\n"); + fprintf (stdout, "--------------------\n"); + + if (a_uri_default_ns) { + gchar *str = cr_string_dup2 (a_uri_default_ns) ; + if (str) { + fprintf (stdout, "%s\n", str); + g_free (str); + str = NULL; + } + } + } + + fprintf (stdout, "******************\n\n"); + a_uri = NULL; /*keep compiler happy */ +} + +static void +test_namespace_declaration (CRDocHandler * a_handler, + CRString * a_prefix, + CRString * a_uri, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "namespace_declaration:\n"); + + if (a_prefix) { + gchar *prefix = NULL; + + prefix = cr_string_dup2 (a_prefix); + if (prefix) { + fprintf (stdout, "prefix: %s\n", prefix); + g_free (prefix); + prefix = NULL; + } + } + + if (a_uri) { + gchar *uri = NULL; + uri = cr_string_dup2 (a_uri) ; + if (uri) { + fprintf (stdout, "uri: %s\n", uri); + g_free (uri); + uri = NULL; + } + } + fprintf (stdout, "\n"); + + fprintf (stdout, "***************\n\n"); + +} + +static void +test_comment (CRDocHandler * a_handler, + CRString * a_comment) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "comment:\n"); + + if (a_comment) { + gchar *comment = NULL; + + comment = cr_string_dup2 (a_comment); + + if (comment) { + fprintf (stdout, "\n/*----------------------\n"); + fprintf (stdout, "%s\n", comment); + fprintf (stdout, "-------------------------*/\n"); + g_free (comment); + comment = NULL; + } + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_selector (CRDocHandler * a_handler, + CRSelector * a_selector_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_selector\n"); + + if (a_selector_list) { + cr_selector_dump (a_selector_list, stdout); + fprintf (stdout, "\n"); + } + + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_selector (CRDocHandler * a_handler, + CRSelector * a_selector_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_selector\n"); + + if (a_selector_list) { + cr_selector_dump (a_selector_list, stdout); + fprintf (stdout, "\n"); + } + + fprintf (stdout, "***************\n\n"); +} + +static void +test_property (CRDocHandler * a_handler, CRString * a_name, + CRTerm * a_expr, gboolean a_important) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "property\n"); + + if (a_name) { + gchar *name = cr_string_dup2 (a_name); + if (name) { + fprintf (stdout, "%s", name); + } + if (a_expr) { + fprintf (stdout, ": "); + cr_term_dump (a_expr, stdout); + } + if (name) { + g_free (name); + name = NULL; + } + fprintf (stdout, "\n"); + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_font_face (CRDocHandler * a_handler, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_font_face\n"); + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_font_face (CRDocHandler * a_handler) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_font_face\n"); + fprintf (stdout, "***************\n\n"); + +} + +static void +test_start_media (CRDocHandler * a_handler, + GList * a_media_list, + CRParsingLocation *a_location) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_media\n"); + + if (a_media_list) { + GList *cur = NULL; + gchar *medium = NULL; + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data == NULL) + continue; + medium = cr_string_dup2 ((CRString *) cur->data); + if (medium == NULL) + continue; + fprintf (stdout, "medium: %s\n", medium); + if (medium) { + g_free (medium); + medium = NULL; + } + } + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_end_media (CRDocHandler * a_handler, + GList * a_media_list) +{ + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_media\n"); + + if (a_media_list) { + GList *cur = NULL; + gchar *medium = NULL; + + for (cur = a_media_list; cur; cur = cur->next) { + if (cur->data == NULL) + continue; + medium = cr_string_dup2 ((CRString *) cur->data); + if (medium == NULL) + continue; + fprintf (stdout, "medium: %s\n", medium); + if (medium) { + g_free (medium); + medium = NULL; + } + } + } + fprintf (stdout, "***************\n\n"); +} + +static void +test_start_page (CRDocHandler * a_handler, + CRString * a_name, + CRString * a_pseudo_page, + CRParsingLocation *a_location) +{ + gchar *name = NULL, + *pseudo_page = NULL; + + g_return_if_fail (a_handler); + + fprintf (stdout, "***************\n"); + fprintf (stdout, "start_page\n"); + + if (a_name) { + name = cr_string_dup2 (a_name); + } + if (a_pseudo_page) { + pseudo_page = cr_string_dup2 (a_pseudo_page); + } + if (name) { + fprintf (stdout, "%s", name); + } + if (pseudo_page) { + fprintf (stdout, ": %s\n", pseudo_page); + } + fprintf (stdout, "***************\n\n"); + if (name) { + g_free (name); + name = NULL; + } + if (pseudo_page) { + g_free (pseudo_page); + pseudo_page = NULL; + } +} + +static void +test_end_page (CRDocHandler * a_handler, + CRString * a_name, + CRString * a_pseudo_page) +{ + gchar *name = NULL, + *pseudo_page = NULL; + + g_return_if_fail (a_handler); + fprintf (stdout, "***************\n"); + fprintf (stdout, "end_page\n"); + + if (a_name) { + name = cr_string_dup2 (a_name); + } + if (a_pseudo_page) { + pseudo_page = cr_string_dup2 (a_pseudo_page) ; + } + if (name) { + fprintf (stdout, "%s", name); + } + if (pseudo_page) { + fprintf (stdout, ": %s\n", pseudo_page); + + } + fprintf (stdout, "***************\n\n"); + if (name) { + g_free (name); + name = NULL; + } + if (pseudo_page) { + g_free (pseudo_page); + pseudo_page = NULL; + } +} + +static void +test_ignorable_at_rule (CRDocHandler * a_handler, + CRString * a_name) +{ + gchar *name = NULL; + + g_return_if_fail (a_handler); + + fprintf (stdout, "*********************\n"); + fprintf (stdout, "ignorable_at_rule\n"); + + if (a_name) { + name = cr_string_dup2 (a_name); + } + if (name) { + fprintf (stdout, "%s\n", name); + } + fprintf (stdout, "*********************\n\n"); +} + +static void +init_test_sac_handler (CRDocHandler * a_handler) +{ + a_handler->start_document = test_start_document; + a_handler->end_document = test_end_document; + a_handler->import_style = test_import_style; + a_handler->namespace_declaration = test_namespace_declaration; + a_handler->comment = test_comment; + a_handler->start_selector = test_start_selector; + a_handler->end_selector = test_end_selector; + a_handler->property = test_property; + a_handler->start_font_face = test_start_font_face; + a_handler->end_font_face = test_end_font_face; + a_handler->start_media = test_start_media; + a_handler->end_media = test_end_media; + a_handler->start_page = test_start_page; + a_handler->end_page = test_end_page; + a_handler->ignorable_at_rule = test_ignorable_at_rule; +} + +/*************************** + *END of TEST SAC document + *handlers. + ***************************/ + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_parser_parse (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + gv_test_handler = cr_doc_handler_new (); + init_test_sac_handler (gv_test_handler); + + parser = cr_parser_new (NULL); + + status = cr_parser_set_sac_handler (parser, gv_test_handler); + + if (status != CR_OK) { + cr_parser_destroy (parser); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + } + + status = cr_parser_set_use_core_grammar (parser, TRUE); + status = cr_parser_parse_file (parser, a_file_uri, CR_ASCII); + + cr_parser_destroy (parser); + + gv_test_handler = NULL; + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + enum CRStatus status = CR_OK; + + cr_test_utils_parse_cmd_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + status = test_cr_parser_parse ((guchar *) options.files_list[0]); + + if (status != CR_OK) { + fprintf (stdout, "KO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test4-main.c b/src/3rdparty/libcroco/tests/test4-main.c new file mode 100644 index 0000000..5cca6ef --- /dev/null +++ b/src/3rdparty/libcroco/tests/test4-main.c @@ -0,0 +1,435 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + + +#include "cr-test-utils.h" +#include "libcroco.h" + +/** + *@file + *Some test facilities for the #CROMParser class. + */ + +CRDocHandler *gv_test_handler = { 0 }; + +const guchar *gv_term_buf = (const guchar *) "106"; + +const guchar *gv_decl_buf = (const guchar *) "toto: tutu, tata"; + +const guchar *gv_decl_list_buf = (const guchar *) "toto: titi; prop1:val1 ; prop2:val2;"; + +const guchar *gv_ruleset_buf = (const guchar *) "s1 > s2 {toto: tutu, tata} "; + +const guchar *gv_at_media_buf = + (const guchar *) "@media print, toto {" " BODY { font-size: 10pt }" " }"; + +const guchar *gv_at_page_buf = (const guchar *) "@page { size :8.5in 11in; margin: 2cm }"; + +const guchar *gv_at_charset_buf = (const guchar *) "@charset \"ISO-8859-1\" ; "; + +const guchar *gv_at_font_face_buf = + (const guchar *) "@font-face {" + " font-family: \"Robson Celtic\";" + " src: url(\"http://site/fonts/rob-celt\")" "}"; + +const guchar *gv_at_import_buf = (const guchar *) "@import \"subs.css\";"; + +static void display_help (char *prg_name); + +static void display_about (char *prg_name); + +static enum CRStatus test_cr_parser_parse (guchar * a_file_uri); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + g_print ("\n\n"); + g_print ("usage: %s <file-to-parse>\n", prg_name); + g_print ("\t <file-to-parse>: the file to parse\n"); + g_print ("\n\n"); + g_print ("Tests the cr_parser_parse () method.\n"); + g_print ("Tests the parsing following the css core syntax\n"); + g_print ("Returns OK if the status is CR_OK, KO otherwise\n"); + g_print ("\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + g_print ("\n\n"); + g_print ("%s is a libcroco CROMParser class test program.\n", + prg_name); + g_print ("%s Parses a file and builds a CSS object model", prg_name); + g_print ("It should run on GNU compliants systems.\n"); + g_print ("\n\n"); + g_print ("Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + g_print ("\n\n"); +} + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_parser_parse (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + CRStyleSheet *stylesheet = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + parser = cr_om_parser_new (NULL); + status = cr_om_parser_parse_file (parser, a_file_uri, CR_ASCII, + &stylesheet); + if (status == CR_OK && stylesheet) { + cr_stylesheet_dump (stylesheet, stdout); + cr_stylesheet_destroy (stylesheet); + } + cr_om_parser_destroy (parser); + + return status; +} + +static enum CRStatus +test_cr_statement_at_page_rule_parse_from_buf (void) +{ + CRStatement *stmt = NULL ; + + stmt = cr_statement_at_page_rule_parse_from_buf + (gv_at_page_buf, CR_UTF_8) ; + if (!stmt) { + return CR_ERROR ; + } + cr_statement_destroy (stmt) ; + return CR_OK ; +} + +static enum CRStatus +test_cr_term_parse_expression_from_buf (void) +{ + guchar *tmp_str = NULL; + CRTerm *term = NULL; + + term = cr_term_parse_expression_from_buf (gv_term_buf, CR_UTF_8); + + if (!term) + return CR_ERROR; + tmp_str = cr_term_to_string (term); + if (term) { + cr_term_destroy (term); + term = NULL; + } + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + return CR_OK; +} + +static enum CRStatus +test_cr_declaration_parse (void) +{ + gchar *tmp_str = NULL; + CRDeclaration *decl = NULL; + + decl = cr_declaration_parse_from_buf (NULL, gv_decl_buf, CR_UTF_8); + if (!decl) + return CR_ERROR; + tmp_str = cr_declaration_to_string (decl, 2); + + if (decl) { + cr_declaration_destroy (decl); + } + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + + return CR_OK; +} + +static enum CRStatus +test_cr_declaration_parse_list (void) +{ + GString *str = NULL; + gchar *tmp_str = NULL; + CRDeclaration *decl = NULL, + *cur_decl = NULL; + + decl = cr_declaration_parse_list_from_buf (gv_decl_list_buf, + CR_UTF_8); + if (!decl) + return CR_ERROR; + str = g_string_new (NULL); + for (cur_decl = decl; cur_decl; cur_decl = cur_decl->next) { + tmp_str = cr_declaration_to_string (cur_decl, 2); + if (tmp_str) { + g_string_append_printf (str, "%s;", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + + } + if (decl) { + cr_declaration_destroy (decl); + } + + if (str) { + g_string_free (str, TRUE); + str = NULL; + } + + return CR_OK; +} + +static enum CRStatus +test_cr_statement_ruleset_parse (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_ruleset_parse_from_buf (gv_ruleset_buf, CR_UTF_8); + g_return_val_if_fail (stmt, CR_ERROR); + + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + return CR_OK; +} + +static enum CRStatus +test_cr_statement_at_media_rule_parse (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_at_media_rule_parse_from_buf (gv_at_media_buf, + CR_UTF_8); + g_return_val_if_fail (stmt, CR_ERROR); + + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + + return CR_OK; +} + + +static enum CRStatus +test_cr_statement_at_charset_rule_parse (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_at_charset_rule_parse_from_buf (gv_at_charset_buf, + CR_UTF_8); + g_return_val_if_fail (stmt, CR_ERROR); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + + return CR_OK; +} + +static enum CRStatus +test_cr_statement_font_face_rule_parse_from_buf (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_font_face_rule_parse_from_buf + (gv_at_font_face_buf, CR_UTF_8); + g_return_val_if_fail (stmt, CR_ERROR); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + + return CR_OK; +} + +static enum CRStatus +test_cr_statement_at_import_rule_parse_from_buf (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_at_import_rule_parse_from_buf (gv_at_import_buf, + CR_UTF_8); + g_return_val_if_fail (stmt, CR_ERROR); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + + return CR_OK; +} + +static enum CRStatus +test_cr_statement_parse_from_buf (void) +{ + CRStatement *stmt = NULL; + + stmt = cr_statement_parse_from_buf (gv_ruleset_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + stmt = cr_statement_parse_from_buf (gv_at_media_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + stmt = cr_statement_parse_from_buf (gv_at_page_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + stmt = cr_statement_parse_from_buf (gv_at_charset_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + stmt = cr_statement_parse_from_buf (gv_at_font_face_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + stmt = cr_statement_parse_from_buf (gv_at_import_buf, CR_UTF_8); + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } else { + return CR_ERROR; + } + + return CR_OK; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + enum CRStatus status = CR_OK; + + status = test_cr_term_parse_expression_from_buf (); + if (status != CR_OK) { + g_print ("\ntest \"cr_term_parse_expression_from_buf failed\""); + } + status = test_cr_declaration_parse (); + if (status != CR_OK) { + g_print ("\n test \"cr_declaration_parse() failed\"\n"); + } + + status = test_cr_declaration_parse_list (); + if (status != CR_OK) { + g_print ("\ntest cr_declaration_parse_list() failed\n"); + } + status = test_cr_statement_ruleset_parse (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_ruleset_parse() failed\n"); + } + + status = test_cr_statement_at_media_rule_parse (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_at_media_rule_parse() failed\n"); + } + test_cr_statement_at_page_rule_parse_from_buf (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_at_page_rule_parse() failed\n"); + return 0; + } + + status = test_cr_statement_at_charset_rule_parse (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_at_charset_rule_parse() failed\n"); + } + + status = test_cr_statement_font_face_rule_parse_from_buf (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_font_face_rule_parse_from_buf() failed\n"); + } + + test_cr_statement_at_import_rule_parse_from_buf (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_at_import_rule() failed\n"); + } + + status = test_cr_statement_parse_from_buf (); + if (status != CR_OK) { + g_print ("\ntest cr_statement_parse_from_buf() failed\n"); + } + + cr_test_utils_parse_cmd_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + status = test_cr_parser_parse ((guchar *) options.files_list[0]); + if (status != CR_OK) { + g_print ("\nKO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test5-main.c b/src/3rdparty/libcroco/tests/test5-main.c new file mode 100644 index 0000000..b10d0b8 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test5-main.c @@ -0,0 +1,255 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "cr-test-utils.h" +#include "cr-libxml-node-iface.h" +#include "libcroco.h" + +#include <libxml/tree.h> +#include <string.h> + +/** + *@file + *Some test facilities for the #CRParser class. + */ + +CRDocHandler *gv_test_handler = { 0 }; + +const guchar *xml_content = + (const guchar *) "<document>" + "<E0>text0</E0> " + "<E1><E1-1>text1</E1-1></E1>" + "<E2 attr2=\"val2\">text2</E2>" + "<E3 attr3=\"val3_1 val3_2 val3_3\">text3</E3>" + "<E4 attr4=\"val4_1-val4_2-val4_3\">text4</E4>" + "<E5 class=\"class5\">text5</E5>" + "<E6 id=\"id6\">text6</E6>" + "<E7 lang=\"fr\">text7</E7>" "</document>"; + +static void + display_help (char *prg_name); + +static void + display_about (char *prg_name); +static enum CRStatus + test_sel_eng (guchar * a_file_uri); + +static void + walk_xml_tree_and_lookup_rules (CRSelEng * a_sel_eng, + CRStyleSheet * a_sheet, xmlNode * a_node); + +/** + *Displays the usage of the test + *facility. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_help (char *prg_name) +{ + g_print ("\n\n"); + g_print ("usage: %s <file-to-parse>\n", prg_name); + g_print ("\t <file-to-parse>: the file to parse\n"); + g_print ("\n\n"); + g_print ("Test the selection engine"); + g_print ("Returns OK if the status is CR_OK, KO otherwise\n"); + g_print ("\n\n"); +} + +/** + *Displays the about text. + *@param a_argc the argc variable passed to the main function. + *@param a_argv the argv variable passed to the main function. + */ +static void +display_about (char *prg_name) +{ + g_print ("\n\n"); + g_print ("%s is a libcroco CROMParser class test program.\n", + prg_name); + g_print ("%s Parses a file and builds a CSS object model", prg_name); + g_print ("It should run on GNU compliants systems.\n"); + g_print ("\n\n"); + g_print ("Initial author: Dodji Seketeli <dodji@seketeli.org>.\n"); + g_print ("\n\n"); +} + +static void +walk_xml_tree_and_lookup_rules (CRSelEng * a_sel_eng, + CRStyleSheet * a_sheet, xmlNode * a_node) +{ + CRStatement **stmts_tab = NULL; + gulong tab_len = 0, + i = 0; + enum CRStatus status = CR_OK; + + xmlNode *cur_node = a_node; + + for (cur_node = a_node; cur_node; cur_node = cur_node->next) { + status = cr_sel_eng_get_matched_rulesets + (a_sel_eng, a_sheet, cur_node, &stmts_tab, &tab_len); + + if (status == CR_OK && tab_len) { + g_print ("'''''''''''''''''''''''''\n"); + g_print ("xml start element: %s\n", cur_node->name); + + for (i = 0; i < tab_len; i++) { + if (stmts_tab[i]) { + g_print ("\n"); + cr_statement_dump (stmts_tab[i], + stdout, 2); + } + } + g_print ("\n\nxml end element: %s\n", cur_node->name); + g_print ("'''''''''''''''''''''''''\n"); + } + + if (stmts_tab) { + g_free (stmts_tab); + stmts_tab = NULL; + } + if (cur_node->children) { + walk_xml_tree_and_lookup_rules + (a_sel_eng, a_sheet, cur_node->children); + } + } +} + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_sel_eng (guchar * a_file_uri) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + CRStyleSheet *stylesheet = NULL; + xmlDoc *xml_doc = NULL; + xmlNode *cur_node = NULL; + CRSelEng *selection_engine = NULL; + + g_return_val_if_fail (a_file_uri, CR_BAD_PARAM_ERROR); + + parser = cr_om_parser_new (NULL); + status = cr_om_parser_parse_file (parser, a_file_uri, CR_ASCII, + &stylesheet); + if (status != CR_OK || !stylesheet) { + cr_utils_trace_info ("Could not parse xml content"); + goto error; + } + + xml_doc = xmlParseMemory ((const char *) xml_content, strlen ((const char *) xml_content)); + if (!xml_doc) { + cr_utils_trace_info ("Could not parse xml content"); + goto error; + + } + + selection_engine = cr_sel_eng_new (&cr_libxml_node_iface); + + cur_node = xml_doc->children; + + walk_xml_tree_and_lookup_rules (selection_engine, + stylesheet, cur_node); + + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + if (xml_doc) { + xmlFreeDoc (xml_doc); + xml_doc = NULL; + } + + if (stylesheet) { + cr_stylesheet_destroy (stylesheet); + stylesheet = NULL; + } + if (selection_engine) { + cr_sel_eng_destroy (selection_engine) ; + selection_engine = NULL ; + } + xmlCleanupParser (); + return status; + + error: + + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + if (xml_doc) { + xmlFreeDoc (xml_doc); + xml_doc = NULL; + } + + if (stylesheet) { + cr_stylesheet_destroy (stylesheet); + stylesheet = NULL; + } + + xmlCleanupParser (); + return CR_ERROR; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + struct Options options; + enum CRStatus status = CR_OK; + + cr_test_utils_parse_cmd_line (argc, argv, &options); + + if (options.display_help == TRUE) { + display_help (argv[0]); + return 0; + } + + if (options.display_about == TRUE) { + display_about (argv[0]); + return 0; + } + + if (options.files_list == NULL) { + display_help (argv[0]); + return 0; + } + + status = test_sel_eng ((guchar *) options.files_list[0]); + + if (status != CR_OK) { + g_print ("\nKO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test6-main.c b/src/3rdparty/libcroco/tests/test6-main.c new file mode 100644 index 0000000..4372c5d --- /dev/null +++ b/src/3rdparty/libcroco/tests/test6-main.c @@ -0,0 +1,84 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms + * of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id$ + */ + +#include <string.h> +#include "libcroco.h" +#include "cr-test-utils.h" + +const guchar *gv_cssbuf = + (const guchar *) ".str0 {stroke:#007844;stroke-width:44}" ".fil0 {fill:url(#id0)}"; + +static enum CRStatus + test_cr_parser_parse (void); + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_parser_parse (void) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + CRStyleSheet *stylesheet = NULL; + + parser = cr_om_parser_new (NULL); + status = cr_om_parser_parse_buf (parser, (guchar *) gv_cssbuf, + strlen ((const char *) gv_cssbuf), + CR_ASCII, &stylesheet); + + if (status == CR_OK && stylesheet) { + cr_stylesheet_dump (stylesheet, stdout); + cr_stylesheet_destroy (stylesheet); + } + cr_om_parser_destroy (parser); + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + enum CRStatus status = CR_OK; + + status = test_cr_parser_parse (); + + if (status != CR_OK) { + g_print ("\nKO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test7-main.c b/src/3rdparty/libcroco/tests/test7-main.c new file mode 100644 index 0000000..f740bea --- /dev/null +++ b/src/3rdparty/libcroco/tests/test7-main.c @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms + * of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include <string.h> +#include "libcroco.h" +#include "cr-test-utils.h" + +const guchar *gv_cssbuf = + (const guchar *) ".exp1n1 {stroke-width:4E6}" + ".exp1n2 {stroke-width:4e6}" + ".exp1n3 {stroke-width:4e+6}" + ".exp2n1 {stroke-width:4E-6}" + ".exp2n2 {stroke-width:4e-6}" + ".exp3n1 {stroke-width:4e6em}" + ".exp3n2 {stroke-width:4e6ex}" + ".exp3n3 {stroke-width:4e6in}" + ".exp4n1 {stroke-width:3.14e4}" + ".exp4n2 {stroke-width:3.14e-4}" + ".e4n2 {stroke-width:.24e-4}" + ".e4n3 {stroke-width:1.e1}"; // This one should be ignored + +static enum CRStatus + test_cr_parser_parse (void); + +/** + *The test of the cr_input_read_byte() method. + *Reads the each byte of a_file_uri using the + *cr_input_read_byte() method. Each byte is send to + *stdout. + *@param a_file_uri the file to read. + *@return CR_OK upon successful completion of the + *function, an error code otherwise. + */ +static enum CRStatus +test_cr_parser_parse (void) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + CRStyleSheet *stylesheet = NULL; + + parser = cr_om_parser_new (NULL); + status = cr_om_parser_parse_buf (parser, (guchar *) gv_cssbuf, + strlen ((const char *) gv_cssbuf), + CR_ASCII, &stylesheet); + + if (status == CR_OK && stylesheet) { + cr_stylesheet_dump (stylesheet, stdout); + // Adding this because my test editor adds a newline character + // at the last line, whereas cr_stylesheet_dump doesn't, which + // results in a diff error/warning. + printf("\n"); + cr_stylesheet_destroy (stylesheet); + } + cr_om_parser_destroy (parser); + + return status; +} + +/** + *The entry point of the testing routine. + */ +int +main (int argc, char **argv) +{ + enum CRStatus status = CR_OK; + + status = test_cr_parser_parse (); + + if (status != CR_OK) { + g_print ("\nKO\n"); + } + + return 0; +} diff --git a/src/3rdparty/libcroco/tests/test8-main.c b/src/3rdparty/libcroco/tests/test8-main.c new file mode 100644 index 0000000..b57c2e4 --- /dev/null +++ b/src/3rdparty/libcroco/tests/test8-main.c @@ -0,0 +1,44 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2022 Thomas Holder + * + * SPDX-License-Identifier: GPL-2.1-or-later + */ + +#include "libcroco.h" +#include <stdio.h> + +int +main (int argc, char **argv) +{ + unsigned i = 0; + CRSelector *selector; + + char const *selector_strings[] = { + // must not have leading whitespace!? + "foo", "foo,bar", "foo , bar ", "foo > bar", ".foo .bar", + }; + + for (i = 0; i < G_N_ELEMENTS (selector_strings); ++i) { + printf ("****************\n"); + printf ("Parsing '%s'\n", selector_strings[i]); + + selector = cr_selector_parse_from_buf ( + (guchar const *) selector_strings[i], CR_UTF_8); + + if (!selector) { + printf ("is NULL\n"); + } else { + cr_selector_dump (selector, stdout); + cr_selector_unref (selector); + printf ("\n"); + } + } + + return 0; +} + +// vi:sw=8:expandtab diff --git a/src/3rdparty/libcroco/tests/testctl b/src/3rdparty/libcroco/tests/testctl new file mode 100755 index 0000000..205112b --- /dev/null +++ b/src/3rdparty/libcroco/tests/testctl @@ -0,0 +1,462 @@ +#! /bin/sh + +##################################### +#This script just runs the tests of +#libcroco, saves their result, diff them +#against a set of reference results and +#displays OK/KO. +#To use it as a tester, the best way is +#just to run 'testctl run' and see the result. +#################################### + +#the directory that contains the tests sources is: +#$TEST_SOURCE_DIR. User can set this var in the environment +#before calling this script. Otherwise, we set it to a default value +if test x$TEST_SOURCE_DIR = x ; then + TEST_SOURCE_DIR=`dirname "$0"` +fi + +#the directory that contains the test outputs is: +#$TEST_OUT_DIR +#User can set this var in the environment before +#calling this script. Otherwise, we set it to a default value. +if test x$TEST_OUT_DIR = x ; then + TEST_OUT_DIR=tests +fi + +if [ -d "$TEST_OUT_DIR/.libs" ]; then + TEST_BIN_DIR="$TEST_OUT_DIR/.libs" +else + TEST_BIN_DIR="$TEST_OUT_DIR" +fi + +#the list of tests to be run +TEST_PROG_LIST= + +#the test input dirs. +TEST_INPUT_DIR=test-inputs + +#the reference test output dirs. +TEST_OUT_REF_DIR=test-output-refs + +#temporary test result dir +TEST_OUTPUT_DIR=test-outputs + +ERROR_REPORT_FILE=tests-error.log +COMMAND_LIST= +COMMAND= +if test x$RUN_VALGRIND = x ; then + RUN_VALGRIND=no +else + RUN_VALGRIND=yes +fi +if test "x$CHECKER" = "x" ; then + CHECKER="valgrind --tool=memcheck" +fi + +VALGRIND_LOGS_DIR=valgrind-logs +VALGRIND= +TEST_PROG= +EGREP="grep -E" + +DIFF=`which diff` +if test "empty$DIFF" = "empty" ; then + echo "You don't have the diff program installed" + echo "Please, install is first" +fi + +display_usage () +{ + echo "" + echo "usage: $0 [general options] <command> [command option]" + echo "" + echo "where general options are:" + echo "====================" + echo "-h|--help displays this help" + echo "" + echo "commands are:" + echo "==============" + echo "run run the tests and display their result" + echo "ref run the tests but saves their output as a reference" + echo "cleanup removes the tmp directories that may have been created" + echo "" + echo "run command options:" + echo "--valgrind runs the test using valgrind" + echo "--testprog <test program>" +} + +parse_command_line () +{ + if test "empty$1" = "empty" ; then + display_usage ; + exit -1 + fi + + while true ; do + arg=$1 + + if test "empty$arg" = "empty" ; then + break ; + fi + + case "$arg" in + -h|--help) + display_usage $@ + exit 0 + ;; + + -*) + echo "$0: unknown option: $arg" + display_usage $@ + exit 0 + ;; + + run|ref|cleanup) + COMMAND_LIST=$arg + REMAINING_ARGS=$@ + echo "REMAINING_ARGS=$REMAINING_ARGS" + break ; + ;; + + *) + display_usage $@ + exit 0 + ;; + esac + done +} + + +#builds the list of available test functions. +build_tests_list () +{ + for TEST_PROG in "$TEST_SOURCE_DIR"/test*.sh "$TEST_OUT_DIR"/test?; do + TEST_PROG=`basename $TEST_PROG` + echo "run test: $TEST_PROG" + TEST_PROG_LIST="$TEST_PROG_LIST $TEST_PROG" + done +} + +#runs a test programs. +#usage run_test_prog <test-name> <reference> <display-on-stdout> +#where "test-name" is the name of the test program to run +#"reference" is a boolean value: yes/no. (the string "yes" or the string no) +#if yes, means that the output of the test is to be saved as a reference. +#if no, means that the output of the test is to be saved as a result of a test. +run_test_prog () +{ + TEST_PROG="$1" + REFERENCE="$2" + DISPLAY_ON_STDOUT="$3" + OUTPUT_DIR= + OUTPUT_SUFFIX= + TEST_INPUT_LIST= + VALGRIND_OPTIONS="--error-limit=no --num-callers=100 --logfile=$TEST_OUT_DIR/$VALGRIND_LOGS_DIR/$TEST_PROG-valgrind.log --leak-check=yes --show-reachable=yes --quiet --suppressions=$TEST_SOURCE_DIR/vg.supp" + if test x$RUN_VALGRIND = xno ; then + VALGRIND= + else + if ! test -x "$TEST_SOURCE_DIR"/valgrind-version.sh ; then + echo "Argh! Could not find file $TEST_SOURCE_DIR/valgrind-version.sh" + exit -1 ; + fi + version=`"$TEST_SOURCE_DIR"/valgrind-version.sh` + if ! test "x$version" = "xokay" ; then + echo "You must install a valgrind version greater than 2.1.1" + echo "version=$version" + exit -1 + fi + if test "x$CHECKER" = "x" ; then + VALGRIND=`which valgrind` + if test "x$VALGRIND" = x ; then + echo "Could not find valgrind in your path" + else + VALGRIND="$VALGRIND $VALGRIND_OPTIONS" + echo "Gonna run the tests with valgrind, using the following options: $VALGRIND_OPTIONS" + fi + else + VALGRIND="$CHECKER $VALGRIND_OPTIONS" + echo "Gonna run the tests with valgrind, using the cmd line: $VALGRIND" + fi + fi + export VALGRIND + case "$TEST_PROG" in + *.sh) is_shell_script=yes ;; + *) is_shell_script=no ;; + esac + + if ! test -d "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" ; then + mkdir "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" + fi + + for TEST_INPUT in `ls -1 "$TEST_SOURCE_DIR/$TEST_INPUT_DIR" | $EGREP "^${TEST_PROG}"'[.0-9]+css$'` ; do + TEST_INPUT_LIST="$TEST_INPUT_LIST $TEST_INPUT" + done + + if test "$REFERENCE" = "yes" ; then + OUTPUT_DIR="$TEST_SOURCE_DIR/$TEST_OUT_REF_DIR" + OUTPUT_SUFFIX=.out + else + OUTPUT_DIR="$TEST_OUT_DIR/$TEST_OUTPUT_DIR" + OUTPUT_SUFFIX=.out + if test ! -d "$OUTPUT_DIR" ; then + echo "creating tmp directory $OUTPUT_DIR ..." + mkdir "$OUTPUT_DIR" + echo "done" + fi + fi + + if test "empty$TEST_INPUT_LIST" != "empty" ; then + for TEST_INPUT in $TEST_INPUT_LIST ; do + TEST_INPUT_NAME=`basename $TEST_INPUT .sh` + if test "$DISPLAY_ON_STDOUT" = "yes" ; then + echo "###############################################" + echo "launching $VALGRIND $TEST_PROG $TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT".... + echo "###############################################" + if test x$is_shell_script = xyes ; then + "$TEST_SOURCE_DIR/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT" + else + $VALGRIND "$TEST_BIN_DIR/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT" + fi + echo "###############################################" + echo "done" + echo "###############################################" + echo "" + else + echo "executing $VALGRIND $TEST_PROG $TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT > $OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX} ..." + $VALGRIND "$TEST_BIN_DIR/$TEST_PROG" "$TEST_SOURCE_DIR/$TEST_INPUT_DIR/$TEST_INPUT" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}" + echo "done" + fi + done + else + if test "$DISPLAY_ON_STDOUT" = "yes" ; then + echo "####################################################" + echo "launching $VALGRIND $TEST_PROG ..." + echo "####################################################" + if test x$is_shell_script = xyes ; then + "$TEST_SOURCE_DIR/$TEST_PROG" + else + $VALGRIND "$TEST_BIN_DIR/$TEST_PROG" + fi + echo "####################################################" + echo "done" + echo "####################################################" + echo "" + else + TEST_INPUT_NAME=`basename "$TEST_PROG" .sh` + echo "executing $VALGRIND $TEST_PROG > $OUTPUT_DIR/${TEST_PROG}${OUTPUT_SUFFIX} ..." + if test x$is_shell_script = xyes ; then + "$TEST_SOURCE_DIR/$TEST_PROG" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}" + else + $VALGRIND "$TEST_BIN_DIR/$TEST_PROG" > "$OUTPUT_DIR/${TEST_INPUT_NAME}${OUTPUT_SUFFIX}" + fi + echo "done" + fi + fi + unset VALGRIND +} + +cleanup_tests () +{ + if test -d "$TEST_OUT_DIR/$TEST_OUTPUT_DIR" ; then + echo "removing $TEST_OUT_DIR/$TEST_OUTPUT_DIR/*" + rm -rf "$TEST_OUT_DIR/$TEST_OUTPUT_DIR" + rm -rf "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" + fi + if test -f "$TEST_OUT_DIR/$ERROR_REPORT_FILE" ; then + rm "$TEST_OUT_DIR/$ERROR_REPORT_FILE" + fi + return 0 +} + +run_test_report () +{ + code=0 + diff -ur --exclude='*CVS*' --exclude='*cvs*' --exclude='Makefile*' --exclude=.arch-ids "$TEST_SOURCE_DIR/$TEST_OUT_REF_DIR" "$TEST_OUT_DIR/$TEST_OUTPUT_DIR" > "$TEST_OUT_DIR/tmpdiff.$$" + NB_DIFF=`wc -l < "$TEST_OUT_DIR/tmpdiff.$$"` + + if test "$NB_DIFF" -eq 0 ; then + echo "/////////////ALL THE TESTS ARE OK :) //////////////////" + rm "$TEST_OUT_DIR/tmpdiff.$$" + else + echo "SOME TESTS ARE KO :(" + mv "$TEST_OUT_DIR/tmpdiff.$$" "$TEST_OUT_DIR/$ERROR_REPORT_FILE" + echo "See $TEST_OUT_DIR/$ERROR_REPORT_FILE to see what's going on" + code=1 + fi + + ################### + #Valgrind errors # + ################### + memleaks=no + for vg_log in `find "$TEST_OUT_DIR/$VALGRIND_LOGS_DIR" -name '*-valgrind.log*' -print` ; do + if test -s "$vg_log" ; then + leaks=`cat "$vg_log" | grep -i leak | grep -v no` + errors=`cat "$vg_log" | grep -w Invalid` + if test "x$leaks" = "x" -a "x$errors" = "x" ; then + rm -f "$vg_log" ; + else + echo "valgrind reported some memory leaks/corruptions in $vg_log" + memleaks=yes + fi + else + rm "$vg_log" + fi + done + if test "x$RUN_VALGRIND" = "xyes" ; then + if test "x$memleaks" = "xno" ; then + echo "Oh, YESSSSSS!, VALGRIND DID NOT DETECT ANY MEMLEAK !! You can go have a beer." + else + echo "Please report these leaks by sending the valgrind logs to the authors of libcroco." + code=2 + fi + fi + return $code +} + +run_test_report_single () +{ + TEST_BASE=`basename "$1" .sh` + code=0 + for reffile in "$TEST_SOURCE_DIR/$TEST_OUT_REF_DIR/$TEST_BASE".*; do + outfile="$TEST_OUT_DIR/$TEST_OUTPUT_DIR/`basename "$reffile"`" + diff -u "$reffile" "$outfile" || code=1 + done + if [ $code -ne 0 ]; then + echo "TEST $TEST_BASE IS KO :(" + fi + return $code +} + +############################ +#Executes the "run" command along with +#its command options. +#For the sake of safety checking +############################ +execute_run_cmd () +{ + args=$@ + test_and_report=no + + if test "$1" != "run" ; then + echo "internal error: first argument should be \'run\'" + return + fi + shift + + while true ; do + cur_arg=$1 + echo "cur_arg=$cur_arg" + + case $cur_arg in + --valgrind) + RUN_VALGRIND=yes + shift + ;; + + "--testprog") + shift + if test "empty$1" = "empty" ; then + echo "--testprog should be followed by a prog name" + display_usage + exit + fi + TEST_PROG=$1 + echo "TEST_PROG=$TEST_PROG" + shift + ;; + + "--test-and-report") + test_and_report=yes + shift + TEST_PROG="$1" + shift + if test -z "$TEST_PROG"; then + echo "--test-and-report must be followed by a prog name" + exit + fi + ;; + + *) + break + ;; + esac + done + + if test "empty$TEST_PROG" = "empty"; then + + cleanup_tests + + build_tests_list ; + if test "empty$TEST_PROG_LIST" = "empty" ; then + echo "could not find any test to run" + exit + fi + + for TEST in $TEST_PROG_LIST ; do + run_test_prog "$TEST" no no; + done + run_test_report ; + elif test "$test_and_report" = "yes"; then + run_test_prog "$TEST_PROG" + run_test_report_single "$TEST_PROG" + else + #run the test and display result on stdout + run_test_prog "$TEST_PROG" no yes ; + fi +} + +############################## +#Analyzes a command string "<command> [command option]" +#and runs the necessary commands. +# +#Must be called with the command line +#starting with a command name. +#all the previous general argument must +#have been stripped away. +############################# +execute_command () +{ + arg="$1" ; + + case "$arg" in + + run) + execute_run_cmd "$@" + ;; + + ref) + build_tests_list ; + if test "empty$TEST_PROG_LIST" = "empty" ; then + echo "could not find any test to run" + exit + fi + + for TEST in $TEST_PROG_LIST ; do + run_test_prog "$TEST" yes no; + done + ;; + + cleanup) + cleanup_tests + ;; + + *) + echo "unknown command" + exit ; + esac + +} + +main () +{ + parse_command_line $@ + + if test "empty$COMMAND_LIST" = "empty" ; then + echo "no test command to execute" + exit + fi + + execute_command $REMAINING_ARGS +} + +main $@ diff --git a/src/3rdparty/libcroco/tests/valgrind-version.sh b/src/3rdparty/libcroco/tests/valgrind-version.sh new file mode 100755 index 0000000..55cbfc2 --- /dev/null +++ b/src/3rdparty/libcroco/tests/valgrind-version.sh @@ -0,0 +1,48 @@ +#! /bin/sh + +valgrind=`which valgrind` +awk=`which awk` +if test "x$valgrind" = "x" ; then + echo "valgrind-not-present" ; + exit ; +fi + + +valgrind_version=`$valgrind --version` +if test "x$valgrind_version" = x ; then + echo "not-present" ; + exit +fi + +if test "x$awk" = x ; then + echo "awk-not-present" + exit +fi + +string_version=`echo $valgrind_version | $awk -F '-' '{print $2}'` + +if test "x$string_version" = "x" ; then + echo "valgrind-version-unknown" + exit +fi + +major=`echo $string_version | $awk -F '.' '{print $1}'` +minor=`echo $string_version | $awk -F '.' '{print $2}'` +micro=`echo $string_version | $awk -F '.' '{print $3}'` + +version=`expr $major \* 10000 + $minor \* 100 + $micro` + +if test "x$version" = "x" ; then + echo "valgrind-version-unknown" + exit ; +fi + +if test "$version" -ge "20101" ; then + echo "okay" + exit ; +else + echo "valgrind-version-lower" + exit ; +fi + + diff --git a/src/3rdparty/libcroco/tests/valgrind.log b/src/3rdparty/libcroco/tests/valgrind.log new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/3rdparty/libcroco/tests/valgrind.log diff --git a/src/3rdparty/libcroco/tests/vg b/src/3rdparty/libcroco/tests/vg new file mode 100755 index 0000000..b1f2c00 --- /dev/null +++ b/src/3rdparty/libcroco/tests/vg @@ -0,0 +1,24 @@ +#!/bin/sh + +### +# +### + +OUTPUT_FILE=valgrind.log +VG=`which valgrind` +VG_OPTIONS="-q --num-callers=100 --leak-check=yes --show-reachable=yes" + +#Some sanity checks +if test "empty$VG" = "empty" ; then + echo "You should install valgrind and set it binary into your" + echo "\$PATH env variable" + echo "go to http://developer.kde.org/~sewardj/ to download valgrind" + exit +fi + + +if test "empty$1" != "empty" ; then + OUTPUT_FILE="$1".vg +fi + +exec $VG $VG_OPTIONS $@ 2>"$OUTPUT_FILE"
\ No newline at end of file diff --git a/src/3rdparty/libcroco/tests/vg.supp b/src/3rdparty/libcroco/tests/vg.supp new file mode 100644 index 0000000..5a3d109 --- /dev/null +++ b/src/3rdparty/libcroco/tests/vg.supp @@ -0,0 +1,57 @@ +{ + g_print_ALLOC_LEAK + Memcheck:Leak + fun:malloc + fun:realloc + fun:g_realloc + fun:g_array_maybe_expand + fun:g_array_set_size + fun:g_static_private_set + fun:g_get_charset + fun:g_print +} + +{ + g_slist_prepend_LEAK + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:g_allocator_new + fun:_g_slist_alloc + fun:g_slist_prepend +} + +{ + g_print_CONVERT_LEAK + Memcheck:Leak + fun:malloc + obj:*libc-2.3.3.so + fun:iconv_open + fun:try_conversion + fun:g_iconv_open + fun:open_converter + fun:g_convert + fun:g_convert_with_fallback + fun:strdup_convert + fun:g_print +} + +{ + g_string_new_CHUNCK_LEAK + Memcheck:Leak + fun:malloc + fun:g_malloc + fun:g_mem_chunk_new + fun:g_string_sized_new + fun:g_string_new +} + +{ + g_list_prepend_LEAK + Memcheck:Leak + fun:calloc + fun:g_malloc0 + fun:g_allocator_new + fun:_g_list_alloc + fun:g_list_prepend +} diff --git a/src/3rdparty/libcroco/win32/Makefile-newvs.am b/src/3rdparty/libcroco/win32/Makefile-newvs.am new file mode 100644 index 0000000..3a91862 --- /dev/null +++ b/src/3rdparty/libcroco/win32/Makefile-newvs.am @@ -0,0 +1,55 @@ +# Centralized autotools file +# Create the Visual Studio 2012/2013/2015 project files +# from the Visual Studio 2010 project files + +# This autotools file, from GLib, can be used in other projects +# that have Visual Studio build support. + +# Author: Fan, Chun-wei +# November 05, 2012 + +# MSVC_BASE_VER: Baseline MSVC 201x version to copy/process project files from (100 for 2010, 120 for 2013) +# MSVC_BASE_VER_LONG: Long Version of baseline Visual Studio 201x version (2010, 2012, 2013, 14, 15) +# MSVC_BASE_TOOLSET: Use if baseline MSVC toolset is not in the form v$(MSVC_BASE_VER)0, meaning v$(MSVC_BASE_TOOLSET) +# MSVC_VER_LONG: Long Version of target Visual Studio (2012, 2013, 14 and so on) +# MSVC_VER: Short Version of target Visual Studio (110 for 2012, 120 for 2013, 140 for 2015, 141 for 2017) +# MSVC_TOOLSET: Use if target MSVC toolsett is not in the form v $(MSVC_VER)0, meaning v$(MSVC_TOOLSET) + +if MSVC_BASE_NO_TOOLSET_SET +MSVC_BASE_TOOLSET = $(MSVC_BASE_VER)0 +endif + +if MSVC_NO_TOOLSET_SET +MSVC_TOOLSET = $(MSVC_VER)0 +endif + +%.sln: + sed 's/11\.00/12\.00/g' < $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp + sed 's/$(MSVC_BASE_VER_LONG)/$(MSVC_VER_LONG)/g' < $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp > $(top_builddir)/win32/vs$(MSVC_VER)/$@ + rm $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp + +%.txt: + sed 's/vs$(MSVC_BASE_VER)/vs$(MSVC_VER)/g' < $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp + sed 's/VS$(MSVC_BASE_VER)/VS$(MSVC_VER)/g' < $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp > $(top_builddir)/win32/vs$(MSVC_VER)/$@ + rm $(top_builddir)/win32/vs$(MSVC_VER)/$@.tmp + +%.vcxproj: + if test -e $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@; then \ + sed 's/v$(MSVC_BASE_TOOLSET)/v$(MSVC_TOOLSET)/g' < $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + else \ + sed 's/v$(MSVC_BASE_TOOLSET)/v$(MSVC_TOOLSET)/g' < $(top_builddir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + fi + +%.props: $(top_builddir)/win32/vs$(MSVC_BASE_VER)/Makefile + if test -e $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@; then \ + sed 's/<VSVer>$(MSVC_BASE_VER)<\/VSVer>/<VSVer>$(MSVC_VER)<\/VSVer>/g' < $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + else \ + sed 's/<VSVer>$(MSVC_BASE_VER)<\/VSVer>/<VSVer>$(MSVC_VER)<\/VSVer>/g' < $(top_builddir)/win32/vs$(MSVC_BASE_VER)/$@ > $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + fi + +%.vcxproj.filters: + if test -e $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@; then \ + cp $(top_srcdir)/win32/vs$(MSVC_BASE_VER)/$@ $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + else \ + cp $(top_builddir)/win32/vs$(MSVC_BASE_VER)/$@ $(top_builddir)/win32/vs$(MSVC_VER)/$@; \ + fi diff --git a/src/3rdparty/libcroco/win32/Makefile.am b/src/3rdparty/libcroco/win32/Makefile.am new file mode 100644 index 0000000..d3cb159 --- /dev/null +++ b/src/3rdparty/libcroco/win32/Makefile.am @@ -0,0 +1,22 @@ +#This file is part of The Croco Library +#This program is free software; you can redistribute it and/or +#modify it under the terms of version 2.1 of the GNU Lesser General Public +#License as published by the Free Software Foundation. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU Lesser General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +#USA + +#Author: Fan, Chun-wei +#See COPYRIGHTS file for copyright information. + +SUBDIRS = vs9 vs10 vs11 vs12 vs14 vs15 vs16 + +EXTRA_DIST = crocopc.py pc_base.py replace.py + diff --git a/src/3rdparty/libcroco/win32/Makefile.msvcproj b/src/3rdparty/libcroco/win32/Makefile.msvcproj new file mode 100644 index 0000000..5224ba0 --- /dev/null +++ b/src/3rdparty/libcroco/win32/Makefile.msvcproj @@ -0,0 +1,153 @@ +# Author: Fan, Chun-wei +# Common Autotools file used to generate Visual Studio 2008+ +# Projects from their templates + +# This autotools file, from GLib, can be used in other projects +# that have Visual Studio build support. + +# * Input variables: +# +# MSVCPROJS - List of Projects that should be generated +# +# * Simple tutorial +# +# Add this to Makefile.am where your library/program is built: +# include <this Makefile.msvcproj> +# MSVCPROJS = YourProject (can be multiple projects in a single srcdir) +# YourProject_FILES = $(libyourlib_1_0_SOURCES) +# YourProject_EXCLUDES = ... # list of sources to exclude, separated by '|', wildcards allowed; use random unused value if none +# (the following 3 lines if headers need to be installed) +# YourProject_HEADERS_DIR = $(libyourlibincludedir) +# YourProject_HEADERS_INST = $(libyourlib_1_0_HEADERS) +# YourProject_HEADERS_EXCLUDES = ... # <list of headers to exclude from installation, separated by '|', wildcards allowed; use random unused value if none> +# +# dist-hook: \ # (or add to it if it is already there, note the vs9 items will also call the vs10 items in the process) +# $(top_builddir)/win32/vs9/YourProject.vcproj \ +# $(top_builddir)/win32/vs9/YourProject.headers # if headers need to be installed +# +# --or, if Visual Studio 2013 or later is required-- +# dist-hook: \ # (or add to it if it is already there, this does -not- call other vs items in the process) +# $(top_builddir)/win32/vs12/YourProject.vcxproj \ +# $(top_builddir)/win32/vs12/YourProject.vs12.headers # if headers need to be installed + +# Private functions + +## Transform the MSVC project filename (no filename extensions) to something which can reference through a variable +## without automake/make complaining, eg Gtk-2.0 -> Gtk_2_0 +_proj_name=$(subst /,_,$(subst -,_,$(subst .,_,$(1)))) +_proj_path_raw:=$(subst $(abs_top_srcdir),,$(abs_srcdir)) +_proj_path=$(subst /,\\,$(_proj_path_raw)) +_proj_subdir_int=$(subst \\\\,\\,\\$(_proj_path)\\) +_proj_subdir=$(subst \\.\\,\\,$(_proj_subdir_int)) + +_proj_files_raw=$(subst /,\\,$($(_proj_name)_FILES)) +_proj_files=$(subst $(srcdir)\\,,$(subst $(builddir)\\,,$(subst $(top_builddir)\\$(_proj_path)\\,\\,$(_proj_files_raw)))) +_proj_filters=$($(_proj_name)_EXCLUDES) + +_proj_headers_raw=$(subst /,\\,$($(_proj_name)_HEADERS_INST)) +_proj_headers=$(subst $(srcdir)\\,,$(subst $(builddir)\\,,$(subst $(top_builddir)\\$(_proj_path)\\,\\,$(_proj_headers_raw)))) +_proj_headers_excludes=$($(_proj_name)_HEADERS_EXCLUDES) + +_headers_dest_posix=$(subst $(includedir),,$($(_proj_name)_HEADERS_DIR)) +_headers_destdir=$(subst /,\\,$(_headers_dest_posix)) + +# +# Creates Visual Studio 2008/2010 projects from items passed in from autotools files +# $(1) - Base Name of the MSVC project files (outputs) +# + +define msvcproj-builder + +$(top_builddir)/win32/vs10/$(1).vcxproj: $(top_builddir)/win32/vs9/$(1).vcproj +$(top_builddir)/win32/vs10/$(1).vcxproj.filters: $(top_builddir)/win32/vs9/$(1).vcproj +$(1).sourcefiles: $(top_builddir)/win32/vs9/$(1).vcproj +$(1).vs10.sourcefiles: $(top_builddir)/win32/vs9/$(1).vcproj +$(1).vs10.sourcefiles.filters: $(top_builddir)/win32/vs9/$(1).vcproj + +$(top_builddir)/win32/vs9/$(1).vcproj: Makefile + -$(RM) $(top_builddir)/win32/vs9/$(1).vcproj + -$(RM) $(top_builddir)/win32/vs10/$(1).vcxproj + -$(RM) $(top_builddir)/win32/vs10/$(1).vcxproj.filters + -$(RM) $(top_builddir)/win32/vs11/$(1).vcxproj + -$(RM) $(top_builddir)/win32/vs11/$(1).vcxproj.filters + -$(RM) $(top_builddir)/win32/vs12/$(1).vcxproj + -$(RM) $(top_builddir)/win32/vs12/$(1).vcxproj.filters + -$(RM) $(top_builddir)/win32/vs14/$(1).vcxproj + -$(RM) $(top_builddir)/win32/vs14/$(1).vcxproj.filters + + + for F in $(_proj_files); do \ + case $$$$F in \ + $(_proj_filters)) \ + ;; \ + *.c|*.cpp|*.cc|*.cxx) \ + echo ' <File RelativePath="..\..'$(_proj_subdir)$$$$F'" />' >>$(1).sourcefiles && \ + echo ' <ClCompile Include="..\..'$(_proj_subdir)$$$$F'" />' >>$(1).vs10.sourcefiles && \ + echo ' <ClCompile Include="..\..'$(_proj_subdir)$$$$F'"><Filter>Source Files</Filter></ClCompile>' >>$(1).vs10.sourcefiles.filters \ + ;; \ + esac; \ + done + + + $(CPP) -P - <$(top_srcdir)/win32/vs9/$(1).vcprojin >$(top_builddir)/win32/vs9/$(1).vcproj + $(CPP) -P - <$(top_srcdir)/win32/vs10/$(1).vcxprojin >$(top_builddir)/win32/vs10/$(1).vcxproj + $(CPP) -P - <$(top_srcdir)/win32/vs10/$(1).vcxproj.filtersin >$(top_builddir)/win32/vs10/$(1).vcxproj.filters + $(RM) $(1).sourcefiles + $(RM) $(1).vs10.sourcefiles + $(RM) $(1).vs10.sourcefiles.filters + +$(top_builddir)/win32/vs10/$(1).vs10.headers: $(top_builddir)/win32/vs9/$(1).headers + +$(top_builddir)/win32/vs9/$(1).headers: Makefile + -$(RM) $(top_builddir)/win32/vs9/$(1).headers + -$(RM) $(top_builddir)/win32/vs10/$(1).vs10.headers + + for F in $(_proj_headers); do \ + case $$$$F in \ + $(_proj_headers_excludes)) \ + ;; \ + *.h|*.hpp|*.hh|*.hxx) \ + echo 'copy ..\..'$(_proj_subdir)$$$$F' $$$$(CopyDir)\include'$(_headers_destdir)'\'$$$$F'
' >>$(top_builddir)/win32/vs9/$(1).headers && \ + echo 'copy ..\..'$(_proj_subdir)$$$$F' $$$$(CopyDir)\include'$(_headers_destdir)'\'$$$$F >>$(top_builddir)/win32/vs10/$(1).vs10.headers \ + ;; \ + esac; \ + done + +$(top_builddir)/win32/vs12/$(1).vcxproj.filters: $(top_builddir)/win32/vs12/$(1).vcxproj + +$(top_builddir)/win32/vs12/$(1).vcxproj: Makefile + -$(RM) $(top_builddir)/win32/vs14/$(1).vcxproj + -$(RM) $(top_builddir)/win32/vs14/$(1).vcxproj.filters + + for F in $(_proj_files); do \ + case $$$$F in \ + $(_proj_filters)) \ + ;; \ + *.c|*.cpp|*.cc|*.cxx) \ + echo ' <ClCompile Include="..\..'$(_proj_subdir)$$$$F'" />' >>$(1).vs12.sourcefiles && \ + echo ' <ClCompile Include="..\..'$(_proj_subdir)$$$$F'"><Filter>Source Files</Filter></ClCompile>' >>$(1).vs12.sourcefiles.filters \ + ;; \ + esac; \ + done + + $(CPP) -P - <$(top_srcdir)/win32/vs12/$(1).vcxprojin >$(top_builddir)/win32/vs12/$(1).vcxproj + $(CPP) -P - <$(top_srcdir)/win32/vs12/$(1).vcxproj.filtersin >$(top_builddir)/win32/vs12/$(1).vcxproj.filters + $(RM) $(1).vs12.sourcefiles + $(RM) $(1).vs12.sourcefiles.filters + +$(top_builddir)/win32/vs12/$(1).vs12.headers: Makefile + -$(RM) $(top_builddir)/win32/vs12/$(1).vs12.headers + + for F in $(_proj_headers); do \ + case $$$$F in \ + $(_proj_headers_excludes)) \ + ;; \ + *.h|*.hpp|*.hh|*.hxx) \ + echo 'copy ..\..'$(_proj_subdir)$$$$F' $$$$(CopyDir)\include'$(_headers_destdir)'\'$$$$F >>$(top_builddir)/win32/vs12/$(1).vs12.headers \ + ;; \ + esac; \ + done + +endef + +$(foreach proj,$(MSVCPROJS),$(eval $(call msvcproj-builder,$(proj)))) diff --git a/src/3rdparty/libcroco/win32/crocopc.py b/src/3rdparty/libcroco/win32/crocopc.py new file mode 100644 index 0000000..9263ac4 --- /dev/null +++ b/src/3rdparty/libcroco/win32/crocopc.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# +# Utility script to generate .pc files for GLib +# for Visual Studio builds, to be used for +# building introspection files + +# Author: Fan, Chun-wei +# Date: March 10, 2016 + +import os +import sys + +from replace import replace_multi +from pc_base import BasePCItems + +def main(argv): + base_pc = BasePCItems() + + base_pc.setup(argv) + croco_version = base_pc.version.split('.') + pkg_replace_items = {'@LIBCROCO_MAJOR_VERSION@': croco_version[0], + '@LIBCROCO_MINOR_VERSION@': croco_version[1]} + + pkg_replace_items.update(base_pc.base_replace_items) + + # Generate libcroco-x.y.pc + replace_multi(base_pc.top_srcdir + '/libcroco.pc.in', + base_pc.srcdir + '/libcroco-' + croco_version[0] + + '.' + croco_version[1] + '.pc', + pkg_replace_items) + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/src/3rdparty/libcroco/win32/pc_base.py b/src/3rdparty/libcroco/win32/pc_base.py new file mode 100644 index 0000000..f7976e8 --- /dev/null +++ b/src/3rdparty/libcroco/win32/pc_base.py @@ -0,0 +1,124 @@ +#!/usr/bin/python +# +# Simple utility script to generate the basic info +# needed in a .pc (pkg-config) file, used especially +# for introspection purposes + +# This can be used in various projects where +# there is the need to generate .pc files, +# and is copied from GLib's $(srcroot)/win32 + +# Author: Fan, Chun-wei +# Date: March 10, 2016 + +import os +import sys +import argparse + +class BasePCItems: + def __init__(self): + self.base_replace_items = {} + self.exec_prefix = '' + self.includedir = '' + self.libdir = '' + self.prefix = '' + self.srcdir = os.path.dirname(__file__) + self.top_srcdir = self.srcdir + '\\..' + self.version = '' + + def setup(self, argv, parser=None): + if parser is None: + parser = argparse.ArgumentParser(description='Setup basic .pc file info') + parser.add_argument('--prefix', help='prefix of the installed library', + required=True) + parser.add_argument('--exec-prefix', + help='prefix of the installed programs, \ + if different from the prefix') + parser.add_argument('--includedir', + help='includedir of the installed library, \ + if different from ${prefix}/include') + parser.add_argument('--libdir', + help='libdir of the installed library, \ + if different from ${prefix}/lib') + parser.add_argument('--version', help='Version of the package', + required=True) + args = parser.parse_args() + + self.version = args.version + + # check whether the prefix and exec_prefix are valid + if not os.path.exists(args.prefix): + raise SystemExit('Specified prefix \'%s\' is invalid' % args.prefix) + + # use absolute paths for prefix + self.prefix = os.path.abspath(args.prefix).replace('\\','/') + + # check and setup the exec_prefix + if getattr(args, 'exec_prefix', None) is None: + exec_prefix_use_shorthand = True + self.exec_prefix = '${prefix}' + else: + if args.exec_prefix.startswith('${prefix}'): + exec_prefix_use_shorthand = True + input_exec_prefix = args.prefix + args.exec_prefix[len('${prefix}'):] + else: + exec_prefix_use_shorthand = False + input_exec_prefix = args.exec_prefix + if not os.path.exists(input_exec_prefix): + raise SystemExit('Specified exec_prefix \'%s\' is invalid' % + args.exec_prefix) + if exec_prefix_use_shorthand is True: + self.exec_prefix = args.exec_prefix.replace('\\','/') + else: + self.exec_prefix = os.path.abspath(input_exec_prefix).replace('\\','/') + + # check and setup the includedir + if getattr(args, 'includedir', None) is None: + self.includedir = '${prefix}/include' + else: + if args.includedir.startswith('${prefix}'): + includedir_use_shorthand = True + input_includedir = args.prefix + args.includedir[len('${prefix}'):] + else: + if args.includedir.startswith('${exec_prefix}'): + includedir_use_shorthand = True + input_includedir = input_exec_prefix + args.includedir[len('${exec_prefix}'):] + else: + includedir_use_shorthand = False + input_includedir = args.includedir + if not os.path.exists(input_includedir): + raise SystemExit('Specified includedir \'%s\' is invalid' % + args.includedir) + if includedir_use_shorthand is True: + self.includedir = args.includedir.replace('\\','/') + else: + self.includedir = os.path.abspath(input_includedir).replace('\\','/') + + # check and setup the libdir + if getattr(args, 'libdir', None) is None: + self.libdir = '${prefix}/lib' + else: + if args.libdir.startswith('${prefix}'): + libdir_use_shorthand = True + input_libdir = args.prefix + args.libdir[len('${prefix}'):] + else: + if args.libdir.startswith('${exec_prefix}'): + libdir_use_shorthand = True + input_libdir = input_exec_prefix + args.libdir[len('${exec_prefix}'):] + else: + libdir_use_shorthand = False + input_libdir = args.libdir + if not os.path.exists(input_libdir): + raise SystemExit('Specified libdir \'%s\' is invalid' % + args.libdir) + if libdir_use_shorthand is True: + self.libdir = args.libdir.replace('\\','/') + else: + self.libdir = os.path.abspath(input_libdir).replace('\\','/') + + # setup dictionary for replacing items in *.pc.in + self.base_replace_items.update({'@VERSION@': self.version}) + self.base_replace_items.update({'@prefix@': self.prefix}) + self.base_replace_items.update({'@exec_prefix@': self.exec_prefix}) + self.base_replace_items.update({'@libdir@': self.libdir}) + self.base_replace_items.update({'@includedir@': self.includedir}) diff --git a/src/3rdparty/libcroco/win32/replace.py b/src/3rdparty/libcroco/win32/replace.py new file mode 100644 index 0000000..3aeceb1 --- /dev/null +++ b/src/3rdparty/libcroco/win32/replace.py @@ -0,0 +1,115 @@ +#!/usr/bin/python +# +# Simple utility script to manipulate +# certain types of strings in a file + +# This can be used in various projects where +# there is the need to replace strings in files, +# and is copied from GLib's $(srcroot)/win32 + +# Author: Fan, Chun-wei +# Date: September 03, 2014 + +import os +import sys +import re +import string +import argparse + +valid_actions = ['remove-prefix', + 'replace-var', + 'replace-str', + 'remove-str'] + +def open_file(filename, mode): + if sys.version_info[0] < 3: + return open(filename, mode=mode) + else: + return open(filename, mode=mode, encoding='utf-8') + +def replace_multi(src, dest, replace_items): + with open_file(src, 'r') as s: + with open_file(dest, 'w') as d: + for line in s: + replace_dict = dict((re.escape(key), value) \ + for key, value in replace_items.items()) + replace_pattern = re.compile("|".join(replace_dict.keys())) + d.write(replace_pattern.sub(lambda m: \ + replace_dict[re.escape(m.group(0))], line)) + +def replace(src, dest, instring, outstring): + replace_item = {instring: outstring} + replace_multi(src, dest, replace_item) + +def check_required_args(args, params): + for param in params: + if getattr(args, param, None) is None: + raise SystemExit('%s: error: --%s argument is required' % (__file__, param)) + +def warn_ignored_args(args, params): + for param in params: + if getattr(args, param, None) is not None: + print('%s: warning: --%s argument is ignored' % (__file__, param)) + +def main(argv): + + parser = argparse.ArgumentParser(description='Process strings in a file.') + parser.add_argument('-a', + '--action', + help='Action to carry out. Can be one of:\n' + 'remove-prefix\n' + 'replace-var\n' + 'replace-str\n' + 'remove-str', + choices=valid_actions) + parser.add_argument('-i', '--input', help='Input file') + parser.add_argument('-o', '--output', help='Output file') + parser.add_argument('--instring', help='String to replace or remove') + parser.add_argument('--var', help='Autotools variable name to replace') + parser.add_argument('--outstring', + help='New String to replace specified string or variable') + parser.add_argument('--removeprefix', help='Prefix of string to remove') + + args = parser.parse_args() + + input_string = '' + output_string = '' + + # We must have action, input, output for all operations + check_required_args(args, ['action','input','output']) + + # Build the arguments by the operation that is to be done, + # to be fed into replace() + + # Get rid of prefixes from a string + if args.action == 'remove-prefix': + check_required_args(args, ['instring','removeprefix']) + warn_ignored_args(args, ['outstring','var']) + input_string = args.removeprefix + args.instring + output_string = args.instring + + # Replace an m4-style variable (those surrounded by @...@) + if args.action == 'replace-var': + check_required_args(args, ['var','outstring']) + warn_ignored_args(args, ['instring','removeprefix']) + input_string = '@' + args.var + '@' + output_string = args.outstring + + # Replace a string + if args.action == 'replace-str': + check_required_args(args, ['instring','outstring']) + warn_ignored_args(args, ['var','removeprefix']) + input_string = args.instring + output_string = args.outstring + + # Remove a string + if args.action == 'remove-str': + check_required_args(args, ['instring']) + warn_ignored_args(args, ['var','outstring','removeprefix']) + input_string = args.instring + output_string = '' + + replace(args.input, args.output, input_string, output_string) + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/src/3rdparty/libcroco/win32/vs10/Makefile.am b/src/3rdparty/libcroco/win32/vs10/Makefile.am new file mode 100644 index 0000000..fcdd2f8 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/Makefile.am @@ -0,0 +1,48 @@ +#This file is part of The Croco Library +#This program is free software; you can redistribute it and/or +#modify it under the terms of version 2.1 of the GNU Lesser General Public +#License as published by the Free Software Foundation. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU Lesser General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +#USA + +#Author: Fan, Chun-wei +#See COPYRIGHTS file for copyright information. + +GENERATED_ITEMS = \ + croco.vcxproj \ + croco.vcxproj.filters \ + croco-install.props \ + croco-version-paths.props + +EXTRA_DIST = \ + croco.vcxprojin \ + croco.vcxproj.filtersin \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + libcroco.sln \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.propsin \ + croco-version-paths.props.in \ + $(GENERATED_ITEMS) + +croco-install.props: $(top_srcdir)/win32/vs10/croco-install.propsin croco.vs10.headers + -$(RM) $(top_builddir)/win32/vs11/croco-install.props + -$(RM) $(top_builddir)/win32/vs12/croco-install.props + -$(RM) $(top_builddir)/win32/vs14/croco-install.props + -$(RM) $(top_builddir)/win32/vs15/croco-install.props + $(CPP) -P - <$(top_srcdir)/win32/vs10/croco-install.propsin > $@ + rm croco.vs10.headers + +DISTCLEANFILES = $(GENERATED_ITEMS) + diff --git a/src/3rdparty/libcroco/win32/vs10/croco-build-defines.props b/src/3rdparty/libcroco/win32/vs10/croco-build-defines.props new file mode 100644 index 0000000..f02e467 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-build-defines.props @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets"> + <Import Project="croco-version-paths.props" /> + </ImportGroup> + <PropertyGroup> + <_PropertySheetDisplayName>crocobuilddefinesprops</_PropertySheetDisplayName> + <OutDir>$(SolutionDir)$(Configuration)\$(PlatformName)\bin\</OutDir> + <IntDir>$(SolutionDir)$(Configuration)\$(PlatformName)\obj\$(ProjectName)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\..\src;..\..;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include\libxml2;$(GlibEtcInstallRoot)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ForcedIncludeFiles>msvc_recommended_pragmas.h;%(ForcedIncludeFiles)</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <AdditionalDependencies>libxml2.lib;glib-2.0.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(GlibEtcInstallRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalOptions Condition="'$(VisualStudioVersion)|$(Platform)'=='11.0|x64'">/HIGHENTROPYVA %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(VisualStudioVersion)|$(Platform)'=='12.0|x64'">/HIGHENTROPYVA %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(VisualStudioVersion)|$(Platform)'=='14.0|x64'">/HIGHENTROPYVA %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(VisualStudioVersion)|$(Platform)'=='15.0|x64'">/HIGHENTROPYVA %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(VisualStudioVersion)|$(Platform)'=='16.0|x64'">/HIGHENTROPYVA %(AdditionalOptions)</AdditionalOptions> + </Link> + </ItemDefinitionGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco-gen-srcs.props b/src/3rdparty/libcroco/win32/vs10/croco-gen-srcs.props new file mode 100644 index 0000000..83f7d30 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-gen-srcs.props @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets"> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros"> + <CopyConfigH>copy ..\..\config.h.win32 ..\..\config.h</CopyConfigH> + <GenerateLibCrocoDef> +echo EXPORTS > $(DefDir)libcroco.def + +cl /EP ..\..\src\libcroco.symbols >> $(DefDir)libcroco.def + </GenerateLibCrocoDef> + </PropertyGroup> + <PropertyGroup> + <_PropertySheetDisplayName>crocogensrcsprops</_PropertySheetDisplayName> + </PropertyGroup> + <ItemGroup> + <BuildMacro Include="CopyConfigH"> + <Value>$(CopyConfigH)</Value> + </BuildMacro> + <BuildMacro Include="GenerateLibCrocoDef"> + <Value>$(GenerateLibCrocoDef)</Value> + </BuildMacro> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco-install.propsin b/src/3rdparty/libcroco/win32/vs10/croco-install.propsin new file mode 100644 index 0000000..ccce87e --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-install.propsin @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets"> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros"> + <BinDir>$(SolutionDir)$(Configuration)\$(Platform)\bin</BinDir> + <LibCrocoDoInstall> +mkdir $(CopyDir) +mkdir $(CopyDir)\bin +copy $(BinDir)\$(LibCrocoDllPrefix)croco$(LibCrocoDllSuffix).dll $(CopyDir)\bin +copy $(BinDir)\$(LibCrocoDllPrefix)croco$(LibCrocoDllSuffix).pdb $(CopyDir)\bin +copy $(BinDir)\csslint.exe $(CopyDir)\bin +copy $(BinDir)\csslint.pdb $(CopyDir)\bin + +mkdir $(CopyDir)\include\libcroco-$(ApiVersion)\libcroco +#include "croco.vs10.headers" + +mkdir $(CopyDir)\lib\pkgconfig +copy $(BinDir)\croco-$(ApiVersion).lib $(CopyDir)\lib +copy ..\libcroco-$(ApiVersion).pc $(CopyDir)\lib\pkgconfig + </LibCrocoDoInstall> + <LibcrocoPCFiles>..\libcroco-$(ApiVersion).pc</LibcrocoPCFiles> + <LibcrocoGenPC>(if not exist $(CopyDir) mkdir $(CopyDir)) & (if exist $(PythonPath)\python.exe $(PythonPath)\python.exe ..\crocopc.py --prefix=$(CopyDir) --version=$(CrocoMajorVersion).$(CrocoMinorVersion).$(CrocoMicroVersion))</LibcrocoGenPC> + </PropertyGroup> + <PropertyGroup> + <_PropertySheetDisplayName>crocoinstallprops</_PropertySheetDisplayName> + </PropertyGroup> + <ItemGroup> + <BuildMacro Include="BinDir"> + <Value>$(BinDir)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoDoInstall"> + <Value>$(LibCrocoDoInstall)</Value> + </BuildMacro> + <BuildMacro Include="LibcrocoPCFiles"> + <Value>$(LibcrocoPCFiles)</Value> + </BuildMacro> + <BuildMacro Include="LibcrocoGenPC"> + <Value>$(LibcrocoGenPC)</Value> + </BuildMacro> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj b/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj new file mode 100644 index 0000000..0cda335 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{00702787-1566-484D-991F-4E7E459BB909}</ProjectGuid> + <RootNamespace>crocoinstall</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Utility</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Utility</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Utility</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Utility</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-install.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-install.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-install.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-install.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <OutDir Condition="'$(Configuration)'=='Debug'">$(GlibEtcInstallRoot)\</OutDir> + <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> + <OutDir Condition="'$(Configuration)'=='Release'">$(GlibEtcInstallRoot)\</OutDir> + <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + </ItemDefinitionGroup> + <ItemGroup> + <CustomBuild Include="..\..\libcroco.pc.in"> + <Message Condition="'$(Configuration)'=='Debug'">Generating .pc files...</Message> + <Command Condition="'$(Configuration)'=='Debug'">$(LibcrocoGenPC)</Command> + <Outputs Condition="'$(Configuration)'=='Debug'">$(LibcrocoPCFiles);%(Outputs)</Outputs> + <Message Condition="'$(Configuration)'=='Release'">Generating .pc files...</Message> + <Command Condition="'$(Configuration)'=='Release'">$(LibcrocoGenPC)</Command> + <Outputs Condition="'$(Configuration)'=='Release'">$(LibcrocoPCFiles);%(Outputs)</Outputs> + </CustomBuild> + <CustomBuild Include="..\..\config.h.win32"> + <Message Condition="'$(Configuration)'=='Debug'">Installing Build Results...</Message> + <AdditionalInputs Condition="'$(Configuration)'=='Debug'">$(LibcrocoPCFiles)</AdditionalInputs> + <Command Condition="'$(Configuration)'=='Debug'">$(LibCrocoDoInstall)</Command> + <Outputs Condition="'$(Configuration)'=='Debug'">blah;%(Outputs)</Outputs> + <Message Condition="'$(Configuration)'=='Release'">Installing Build Results...</Message> + <AdditionalInputs Condition="'$(Configuration)'=='Release'">$(LibcrocoPCFiles)</AdditionalInputs> + <Command Condition="'$(Configuration)'=='Release'">$(LibCrocoDoInstall)</Command> + <Outputs Condition="'$(Configuration)'=='Release'">blah;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="croco.vcxproj"> + <Project>{4afe9f9b-7f78-41a8-b066-c7ca89938aba}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="csslint.vcxproj"> + <Project>{345080b1-9c5b-44b8-98d7-7381d50f3e13}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj.filters b/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj.filters new file mode 100644 index 0000000..9386b54 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-install.vcxproj.filters @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\..\config.h.win32"><Filter>Resource Files</Filter></CustomBuild> + <CustomBuild Include="..\..\libcroco.pc.in"><Filter>Resource Files</Filter></CustomBuild> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco-version-paths.props.in b/src/3rdparty/libcroco/win32/vs10/croco-version-paths.props.in new file mode 100644 index 0000000..eb4000f --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco-version-paths.props.in @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="UserMacros"> + <CrocoMajorVersion>@LIBCROCO_MAJOR_VERSION@</CrocoMajorVersion> + <CrocoMinorVersion>@LIBCROCO_MINOR_VERSION@</CrocoMinorVersion> + <CrocoMicroVersion>@LIBCROCO_MICRO_VERSION@</CrocoMicroVersion> + <ApiVersion>$(CrocoMajorVersion).$(CrocoMinorVersion)</ApiVersion> + <VSVer>10</VSVer> + <GlibEtcInstallRoot>$(SolutionDir)\..\..\..\vs$(VSVer)\$(Platform)</GlibEtcInstallRoot> + <CopyDir>$(GlibEtcInstallRoot)</CopyDir> + <DefDir>$(SolutionDir)$(Configuration)\$(PlatformName)\obj\$(ProjectName)\</DefDir> + <LibCrocoLibtoolCompatibleDllPrefix>lib</LibCrocoLibtoolCompatibleDllPrefix> + <LibCrocoLibtoolCompatibleDllSuffix>-$(ApiVersion)-0</LibCrocoLibtoolCompatibleDllSuffix> + <LibCrocoSeparateVSDllPrefix /> + <LibCrocoSeparateVSDllSuffix>-$(ApiVersion)-vs$(VSVer)</LibCrocoSeparateVSDllSuffix> + <LibCrocoDllPrefix>$(LibCrocoSeparateVSDllPrefix)</LibCrocoDllPrefix> + <LibCrocoDllSuffix>$(LibCrocoSeparateVSDllSuffix)</LibCrocoDllSuffix> + <PythonPath>c:\python34</PythonPath> + </PropertyGroup> + <PropertyGroup> + <_PropertySheetDisplayName>crocoversionpathsprops</_PropertySheetDisplayName> + </PropertyGroup> + <ItemGroup> + <BuildMacro Include="CrocoMajorVersion"> + <Value>$(CrocoMajorVersion)</Value> + </BuildMacro> + <BuildMacro Include="CrocoMinorVersion"> + <Value>$(CrocoMinorVersion)</Value> + </BuildMacro> + <BuildMacro Include="CrocoMicroVersion"> + <Value>$(CrocoMicroVersion)</Value> + </BuildMacro> + <BuildMacro Include="ApiVersion"> + <Value>$(ApiVersion)</Value> + </BuildMacro> + <BuildMacro Include="VSVer"> + <Value>$(VSVer)</Value> + </BuildMacro> + <BuildMacro Include="GlibEtcInstallRoot"> + <Value>$(GlibEtcInstallRoot)</Value> + </BuildMacro> + <BuildMacro Include="CopyDir"> + <Value>$(CopyDir)</Value> + </BuildMacro> + <BuildMacro Include="DefDir"> + <Value>$(DefDir)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoLibtoolCompatibleDllPrefix"> + <Value>$(LibCrocoLibtoolCompatibleDllPrefix)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoLibtoolCompatibleDllSuffix"> + <Value>$(LibCrocoLibtoolCompatibleDllSuffix)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoSeparateVSDllPrefix"> + <Value>$(LibCrocoSeparateVSDllPrefix)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoSeparateVSDllSuffix"> + <Value>$(LibCrocoSeparateVSDllSuffix)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoDllPrefix"> + <Value>$(LibCrocoDllPrefix)</Value> + </BuildMacro> + <BuildMacro Include="LibCrocoDllSuffix"> + <Value>$(LibCrocoDllSuffix)</Value> + </BuildMacro> + <BuildMacro Include="PythonPath"> + <Value>$(PythonPath)</Value> + </BuildMacro> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco.vcxproj.filtersin b/src/3rdparty/libcroco/win32/vs10/croco.vcxproj.filtersin new file mode 100644 index 0000000..4cce25f --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco.vcxproj.filtersin @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Sources"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Headers"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> +#include "croco.vs10.sourcefiles.filters" + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\..\config.h.win32"><Filter>Resource Files</Filter></CustomBuild> + <CustomBuild Include="..\..\src\libcroco.symbols"><Filter>Resource Files</Filter></CustomBuild> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/croco.vcxprojin b/src/3rdparty/libcroco/win32/vs10/croco.vcxprojin new file mode 100644 index 0000000..e81481b --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/croco.vcxprojin @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}</ProjectGuid> + <RootNamespace>libcroco</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-gen-srcs.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-gen-srcs.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-gen-srcs.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-gen-srcs.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <LinkIncremental Condition="'$(Configuration)'=='Debug'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll</OutputFile> + <ModuleDefinitionFile>$(IntDir)libcroco.def</ModuleDefinitionFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(TargetDir)$(ProjectName)-$(ApiVersion).lib</ImportLibrary> + <ProgramDatabaseFile>$(TargetDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).pdb</ProgramDatabaseFile> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll</OutputFile> + <ModuleDefinitionFile>$(IntDir)libcroco.def</ModuleDefinitionFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <ImportLibrary>$(TargetDir)$(ProjectName)-$(ApiVersion).lib</ImportLibrary> + <ProgramDatabaseFile>$(TargetDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).pdb</ProgramDatabaseFile> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll</OutputFile> + <ModuleDefinitionFile>$(IntDir)libcroco.def</ModuleDefinitionFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <ImportLibrary>$(TargetDir)$(ProjectName)-$(ApiVersion).lib</ImportLibrary> + <ProgramDatabaseFile>$(TargetDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).pdb</ProgramDatabaseFile> + <TargetMachine>MachineX64</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll</OutputFile> + <ModuleDefinitionFile>$(IntDir)libcroco.def</ModuleDefinitionFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <ImportLibrary>$(TargetDir)$(ProjectName)-$(ApiVersion).lib</ImportLibrary> + <ProgramDatabaseFile>$(TargetDir)$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).pdb</ProgramDatabaseFile> + <TargetMachine>MachineX64</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> +#include "croco.vs10.sourcefiles" + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\..\config.h.win32"> + <Message Condition="'$(Configuration)'=='Debug'">Copying config.h from config.h.win32...</Message> + <Command Condition="'$(Configuration)'=='Debug'">$(CopyConfigH)</Command> + <Outputs Condition="'$(Configuration)'=='Debug'">..\..\config.h;%(Outputs)</Outputs> + <Message Condition="'$(Configuration)'=='Release'">Copying config.h from config.h.win32...</Message> + <Command Condition="'$(Configuration)'=='Release'">$(CopyConfigH)</Command> + <Outputs Condition="'$(Configuration)'=='Release'">..\..\config.h;%(Outputs)</Outputs> + </CustomBuild> + <CustomBuild Include="..\..\src\libcroco.symbols"> + <Message Condition="'$(Configuration)'=='Debug'">Generating libcroco.def...</Message> + <Command Condition="'$(Configuration)'=='Debug'">$(GenerateLibCrocoDef)</Command> + <Outputs Condition="'$(Configuration)'=='Debug'">$(IntDir)\libcroco.def;%(Outputs)</Outputs> + <Message Condition="'$(Configuration)'=='Release'">Generating libcroco.def...</Message> + <Command Condition="'$(Configuration)'=='Release'">$(GenerateLibCrocoDef)</Command> + <Outputs Condition="'$(Configuration)'=='Release'">$(IntDir)\libcroco.def;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj b/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj new file mode 100644 index 0000000..452aa4a --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{345080B1-9C5B-44B8-98D7-7381D50F3E13}</ProjectGuid> + <RootNamespace>csslint</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="croco-build-defines.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <LinkIncremental Condition="'$(Configuration)'=='Debug'">true</LinkIncremental> + <LinkIncremental Condition="'$(Configuration)'=='Release'">false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <TargetMachine>MachineX64</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Midl> + <TargetEnvironment>X64</TargetEnvironment> + </Midl> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX64</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\csslint\csslint.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="croco.vcxproj"> + <Project>{4afe9f9b-7f78-41a8-b066-c7ca89938aba}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj.filters b/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj.filters new file mode 100644 index 0000000..1145315 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/csslint.vcxproj.filters @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Sources"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\csslint\csslint.c"> + <Filter>Sources</Filter> + </ClCompile> + </ItemGroup> +</Project> diff --git a/src/3rdparty/libcroco/win32/vs10/libcroco.sln b/src/3rdparty/libcroco/win32/vs10/libcroco.sln new file mode 100644 index 0000000..2077ef1 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs10/libcroco.sln @@ -0,0 +1,46 @@ +
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croco", "croco.vcxproj", "{4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csslint", "csslint.vcxproj", "{345080B1-9C5B-44B8-98D7-7381D50F3E13}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croco-install", "croco-install.vcxproj", "{00702787-1566-484D-991F-4E7E459BB909}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|Win32.Build.0 = Debug|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|x64.ActiveCfg = Debug|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|x64.Build.0 = Debug|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|Win32.ActiveCfg = Release|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|Win32.Build.0 = Release|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|x64.ActiveCfg = Release|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|x64.Build.0 = Release|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|Win32.ActiveCfg = Debug|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|Win32.Build.0 = Debug|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|x64.ActiveCfg = Debug|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|x64.Build.0 = Debug|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|Win32.ActiveCfg = Release|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|Win32.Build.0 = Release|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|x64.ActiveCfg = Release|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|x64.Build.0 = Release|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|Win32.ActiveCfg = Debug|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|Win32.Build.0 = Debug|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|x64.ActiveCfg = Debug|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|x64.Build.0 = Debug|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|Win32.ActiveCfg = Release|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|Win32.Build.0 = Release|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|x64.ActiveCfg = Release|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/3rdparty/libcroco/win32/vs11/Makefile.am b/src/3rdparty/libcroco/win32/vs11/Makefile.am new file mode 100644 index 0000000..b5f9ea9 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs11/Makefile.am @@ -0,0 +1,39 @@ +# This file is part of The Croco Library +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +# Author: Fan, Chun-wei +# See COPYRIGHTS file for copyright information. + +EXTRA_DIST = \ + libcroco.sln \ + croco.vcxproj \ + croco.vcxproj.filters \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.props \ + croco-version-paths.props + +DISTCLEANFILES = $(EXTRA_DIST) + +MSVC_BASE_VER = 10 +MSVC_BASE_VER_LONG = 2010 +MSVC_VER = 11 +MSVC_VER_LONG = 2012 + +include $(top_srcdir)/win32/Makefile-newvs.am diff --git a/src/3rdparty/libcroco/win32/vs12/Makefile.am b/src/3rdparty/libcroco/win32/vs12/Makefile.am new file mode 100644 index 0000000..a3d6db1 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs12/Makefile.am @@ -0,0 +1,39 @@ +# This file is part of The Croco Library +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +# Author: Fan, Chun-wei +# See COPYRIGHTS file for copyright information. + +EXTRA_DIST = \ + libcroco.sln \ + croco.vcxproj \ + croco.vcxproj.filters \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.props \ + croco-version-paths.props + +DISTCLEANFILES = $(EXTRA_DIST) + +MSVC_BASE_VER = 10 +MSVC_BASE_VER_LONG = 2010 +MSVC_VER = 12 +MSVC_VER_LONG = 2013 + +include $(top_srcdir)/win32/Makefile-newvs.am diff --git a/src/3rdparty/libcroco/win32/vs14/Makefile.am b/src/3rdparty/libcroco/win32/vs14/Makefile.am new file mode 100644 index 0000000..d68e3bf --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs14/Makefile.am @@ -0,0 +1,39 @@ +# This file is part of The Croco Library +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +# Author: Fan, Chun-wei +# See COPYRIGHTS file for copyright information. + +EXTRA_DIST = \ + libcroco.sln \ + croco.vcxproj \ + croco.vcxproj.filters \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.props \ + croco-version-paths.props + +DISTCLEANFILES = $(EXTRA_DIST) + +MSVC_BASE_VER = 10 +MSVC_BASE_VER_LONG = 2010 +MSVC_VER = 14 +MSVC_VER_LONG = 14 + +include $(top_srcdir)/win32/Makefile-newvs.am diff --git a/src/3rdparty/libcroco/win32/vs15/Makefile.am b/src/3rdparty/libcroco/win32/vs15/Makefile.am new file mode 100644 index 0000000..0a4afa0 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs15/Makefile.am @@ -0,0 +1,40 @@ +# This file is part of The Croco Library +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +# Author: Fan, Chun-wei +# See COPYRIGHTS file for copyright information. + +EXTRA_DIST = \ + libcroco.sln \ + croco.vcxproj \ + croco.vcxproj.filters \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.props \ + croco-version-paths.props + +DISTCLEANFILES = $(EXTRA_DIST) + +MSVC_BASE_VER = 10 +MSVC_BASE_VER_LONG = 2010 +MSVC_VER = 15 +MSVC_VER_LONG = 15 +MSVC_TOOLSET = 141 + +include $(top_srcdir)/win32/Makefile-newvs.am diff --git a/src/3rdparty/libcroco/win32/vs16/Makefile.am b/src/3rdparty/libcroco/win32/vs16/Makefile.am new file mode 100644 index 0000000..a622c19 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs16/Makefile.am @@ -0,0 +1,40 @@ +# This file is part of The Croco Library +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + +# Author: Fan, Chun-wei +# See COPYRIGHTS file for copyright information. + +EXTRA_DIST = \ + libcroco.sln \ + croco.vcxproj \ + croco.vcxproj.filters \ + csslint.vcxproj \ + csslint.vcxproj.filters \ + croco-install.vcxproj \ + croco-install.vcxproj.filters \ + croco-build-defines.props \ + croco-gen-srcs.props \ + croco-install.props \ + croco-version-paths.props + +DISTCLEANFILES = $(EXTRA_DIST) + +MSVC_BASE_VER = 10 +MSVC_BASE_VER_LONG = 2010 +MSVC_VER = 16 +MSVC_VER_LONG = 16 +MSVC_TOOLSET = 142 + +include $(top_srcdir)/win32/Makefile-newvs.am diff --git a/src/3rdparty/libcroco/win32/vs9/Makefile.am b/src/3rdparty/libcroco/win32/vs9/Makefile.am new file mode 100644 index 0000000..9128036 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/Makefile.am @@ -0,0 +1,39 @@ +#This file is part of The Croco Library +#This program is free software; you can redistribute it and/or +#modify it under the terms of version 2.1 of the GNU Lesser General Public +#License as published by the Free Software Foundation. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU Lesser General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +#USA + +#Author: Fan, Chun-wei +#See COPYRIGHTS file for copyright information. + +GENERATED_ITEMS = \ + croco.vcproj \ + croco-install.vsprops \ + croco-version-paths.vsprops + +EXTRA_DIST = \ + croco.vcprojin \ + csslint.vcproj \ + croco-install.vcproj \ + libcroco.sln \ + croco-build-defines.vsprops \ + croco-gen-srcs.vsprops \ + croco-install.vspropsin \ + croco-version-paths.vsprops.in \ + $(GENERATED_ITEMS) + +croco-install.vsprops: $(top_srcdir)/win32/vs9/croco-install.vspropsin croco.headers + $(CPP) -P - <$(top_srcdir)/win32/vs9/croco-install.vspropsin >$@ + rm croco.headers + +DISTCLEANFILES = $(GENERATED_ITEMS) diff --git a/src/3rdparty/libcroco/win32/vs9/croco-build-defines.vsprops b/src/3rdparty/libcroco/win32/vs9/croco-build-defines.vsprops new file mode 100644 index 0000000..a081b7b --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco-build-defines.vsprops @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioPropertySheet + ProjectType="Visual C++" + Version="8.00" + Name="crocobuilddefinesprops" + InheritedPropertySheets=".\croco-version-paths.vsprops" + OutputDirectory="$(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin" + IntermediateDirectory="$(SolutionDir)$(ConfigurationName)\$(PlatformName)\obj\$(ProjectName)" + > + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\..\src;..\..;$(GlibEtcInstallRoot)\include\glib-2.0;$(GlibEtcInstallRoot)\lib\glib-2.0\include;$(GlibEtcInstallRoot)\include\libxml2;$(GlibEtcInstallRoot)\include" + PreprocessorDefinitions="HAVE_CONFIG_H" + ForcedIncludeFiles="msvc_recommended_pragmas.h" + AdditionalOptions="/MP" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libxml2.lib glib-2.0.lib" + AdditionalLibraryDirectories="$(GlibEtcInstallRoot)\lib" + /> +</VisualStudioPropertySheet> diff --git a/src/3rdparty/libcroco/win32/vs9/croco-gen-srcs.vsprops b/src/3rdparty/libcroco/win32/vs9/croco-gen-srcs.vsprops new file mode 100644 index 0000000..5be8fe7 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco-gen-srcs.vsprops @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioPropertySheet + ProjectType="Visual C++" + Version="8.00" + Name="crocogensrcsprops" + InheritedPropertySheets=".\croco-build-defines.vsprops" + > + <UserMacro + Name="CopyConfigH" + Value="copy ..\..\config.h.win32 ..\..\config.h" + /> + <UserMacro + Name="GenerateLibCrocoDef" + Value=" +echo EXPORTS > $(DefDir)\libcroco.def
 +cl /EP ..\..\src\libcroco.symbols >> $(DefDir)\libcroco.def
 + " + /> +</VisualStudioPropertySheet> diff --git a/src/3rdparty/libcroco/win32/vs9/croco-install.vcproj b/src/3rdparty/libcroco/win32/vs9/croco-install.vcproj new file mode 100644 index 0000000..a48547c --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco-install.vcproj @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="big5"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="croco-install" + ProjectGUID="{00702787-1566-484D-991F-4E7E459BB909}" + RootNamespace="crocoinstall" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(GlibEtcInstallRoot)" + ConfigurationType="10" + InheritedPropertySheets=".\croco-install.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPostBuildEventTool" + CommandLine="$(LibCrocoDoInstall)" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(GlibEtcInstallRoot)" + InheritedPropertySheets=".\croco-install.vsprops" + ConfigurationType="10" + CharacterSet="2" + DeleteExtensionsOnClean="" + > + <Tool + Name="VCPostBuildEventTool" + CommandLine="$(LibCrocoDoInstall)" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(GlibEtcInstallRoot)" + ConfigurationType="10" + InheritedPropertySheets=".\croco-install.vsprops" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPostBuildEventTool" + CommandLine="$(LibCrocoDoInstall)" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(GlibEtcInstallRoot)" + InheritedPropertySheets=".\croco-install.vsprops" + ConfigurationType="10" + CharacterSet="2" + WholeProgramOptimization="1" + DeleteExtensionsOnClean="" + > + <Tool + Name="VCPostBuildEventTool" + CommandLine="$(LibCrocoDoInstall)" + /> + </Configuration> + </Configurations> + <Files> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + <File RelativePath="..\..\libcroco.pc.in"> + <FileConfiguration Name="Debug|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="Generating .pc files..." + CommandLine="$(LibcrocoGenPC)" + Outputs="..\libcroco-0.6.pc" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="Generating .pc files..." + CommandLine="$(LibcrocoGenPC)" + Outputs="..\libcroco-0.6.pc" + /> + </FileConfiguration> + <FileConfiguration Name="Debug|x64"> + <Tool + Name="VCCustomBuildTool" + Description="Generating .pc files..." + CommandLine="$(LibcrocoGenPC)" + Outputs="..\libcroco-0.6.pc" + /> + </FileConfiguration> + <FileConfiguration Name="Release|x64"> + <Tool + Name="VCCustomBuildTool" + Description="Generating .pc files..." + CommandLine="$(LibcrocoGenPC)" + Outputs="..\libcroco-0.6.pc" + /> + </FileConfiguration> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/3rdparty/libcroco/win32/vs9/croco-install.vspropsin b/src/3rdparty/libcroco/win32/vs9/croco-install.vspropsin new file mode 100644 index 0000000..63a8afb --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco-install.vspropsin @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioPropertySheet + ProjectType="Visual C++" + Version="8.00" + Name="crocoinstallprops" + InheritedPropertySheets=".\croco-build-defines.vsprops" + > + <UserMacro + Name="LibCrocoDoInstall" + Value=" +mkdir $(GlibEtcInstallRoot)
 +mkdir $(GlibEtcInstallRoot)\bin
 +copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\$(LibCrocoDllPrefix)croco$(LibCrocoDllSuffix).dll $(CopyDir)\bin
 +copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\$(LibCrocoDllPrefix)croco$(LibCrocoDllSuffix).pdb $(CopyDir)\bin
 +copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\csslint.exe $(CopyDir)\bin
 +copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\csslint.pdb $(CopyDir)\bin
 + +mkdir $(CopyDir)\lib\pkgconfig
 +copy ..\libcroco-$(ApiVersion).pc $(CopyDir)\lib\pkgconfig
 + +mkdir $(CopyDir)\include\libcroco-$(ApiVersion)\libcroco
 +#include "croco.headers" + +mkdir $(CopyDir)\lib
 +copy $(SolutionDir)$(ConfigurationName)\$(PlatformName)\bin\croco-$(ApiVersion).lib $(CopyDir)\lib
 +" + /> + <UserMacro + Name="LibcrocoGenPC" + Value="(if not exist $(CopyDir) mkdir $(CopyDir)) & (if exist $(PythonPath)\python.exe $(PythonPath)\python.exe ..\crocopc.py --prefix=$(CopyDir) --version=$(CrocoMajorVersion).$(CrocoMinorVersion).$(CrocoMicroVersion))" + /> +</VisualStudioPropertySheet> diff --git a/src/3rdparty/libcroco/win32/vs9/croco-version-paths.vsprops.in b/src/3rdparty/libcroco/win32/vs9/croco-version-paths.vsprops.in new file mode 100644 index 0000000..d03f5e8 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco-version-paths.vsprops.in @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioPropertySheet + ProjectType="Visual C++" + Version="8.00" + Name="crocoversionpathsprops" + > + <UserMacro + Name="CrocoMajorVersion" + Value="@LIBCROCO_MAJOR_VERSION@" + /> + <UserMacro + Name="CrocoMinorVersion" + Value="@LIBCROCO_MINOR_VERSION@" + /> + <UserMacro + Name="CrocoMicroVersion" + Value="@LIBCROCO_MICRO_VERSION@" + /> + <UserMacro + Name="ApiVersion" + Value="$(CrocoMajorVersion).$(CrocoMinorVersion)" + /> + <UserMacro + Name="VSVer" + Value="9" + /> + <UserMacro + Name="GlibEtcInstallRoot" + Value="$(SolutionDir)\..\..\..\vs$(VSVer)\$(PlatformName)" + /> + <UserMacro + Name="CopyDir" + Value="$(GlibEtcInstallRoot)" + /> + <UserMacro + Name="DefDir" + Value="$(SolutionDir)$(ConfigurationName)\$(PlatformName)\obj\$(ProjectName)" + /> + <UserMacro + Name="LibCrocoLibtoolCompatibleDllPrefix" + Value="lib" + /> + <UserMacro + Name="LibCrocoLibtoolCompatibleDllSuffix" + Value="-$(ApiVersion)-0" + /> + <UserMacro + Name="LibCrocoSeparateVSDllPrefix" + Value="" + /> + <UserMacro + Name="LibCrocoSeparateVSDllSuffix" + Value="-$(ApiVersion)-vs$(VSVer)" + /> + <!-- Change these two to LibCrocoLibtoolCompatibleDllPrefix and + LibCrocoLibtoolCompatibleDllSuffix if that is what you want --> + <UserMacro + Name="LibCrocoDllPrefix" + Value="$(LibCrocoSeparateVSDllPrefix)" + /> + <UserMacro + Name="LibCrocoDllSuffix" + Value="$(LibCrocoSeparateVSDllSuffix)" + /> + <UserMacro + Name="PythonPath" + Value="c:\python27" + /> +</VisualStudioPropertySheet> diff --git a/src/3rdparty/libcroco/win32/vs9/croco.vcprojin b/src/3rdparty/libcroco/win32/vs9/croco.vcprojin new file mode 100644 index 0000000..82df5a8 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/croco.vcprojin @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="big5"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="croco" + ProjectGUID="{4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}" + RootNamespace="libcroco" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + InheritedPropertySheets=".\croco-gen-srcs.vsprops" + ConfigurationType="2" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + ForcedIncludeFiles="" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + OutputFile="$(OutDir)\$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll" + LinkIncremental="2" + ModuleDefinitionFile="$(IntDir)\libcroco.def" + GenerateDebugInformation="true" + SubSystem="2" + ImportLibrary="$(TargetDir)$(ProjectName)-$(ApiVersion).lib" + TargetMachine="1" + /> + </Configuration> + <Configuration + Name="Release|Win32" + InheritedPropertySheets=".\croco-gen-srcs.vsprops" + ConfigurationType="2" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + ForcedIncludeFiles="" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + OutputFile="$(OutDir)\$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll" + LinkIncremental="1" + ModuleDefinitionFile="$(IntDir)\libcroco.def" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(TargetDir)$(ProjectName)-$(ApiVersion).lib" + TargetMachine="1" + /> + </Configuration> + <Configuration + Name="Debug|x64" + InheritedPropertySheets=".\croco-gen-srcs.vsprops" + ConfigurationType="2" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + ForcedIncludeFiles="" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + OutputFile="$(OutDir)\$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll" + LinkIncremental="2" + ModuleDefinitionFile="$(IntDir)\libcroco.def" + GenerateDebugInformation="true" + SubSystem="2" + ImportLibrary="$(TargetDir)$(ProjectName)-$(ApiVersion).lib" + TargetMachine="17" + /> + </Configuration> + <Configuration + Name="Release|x64" + InheritedPropertySheets=".\croco-gen-srcs.vsprops" + ConfigurationType="2" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + ForcedIncludeFiles="" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + OutputFile="$(OutDir)\$(LibCrocoDllPrefix)$(ProjectName)$(LibCrocoDllSuffix).dll" + LinkIncremental="1" + ModuleDefinitionFile="$(IntDir)\libcroco.def" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(TargetDir)$(ProjectName)-$(ApiVersion).lib" + TargetMachine="17" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Sources" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > +#include "croco.sourcefiles" + </Filter> + <Filter + Name="Headers" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + <File RelativePath="..\..\config.h.win32"> + <FileConfiguration Name="Debug|Win32"> + <Tool Name="VCCustomBuildTool" + Description="Copying config.h from config.h.win32..." + CommandLine="$(CopyConfigH)" + Outputs="..\..\config.h" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32"> + <Tool Name="VCCustomBuildTool" + Description="Copying config.h from config.h.win32..." + CommandLine="$(CopyConfigH)" + Outputs="..\..\config.h" + /> + </FileConfiguration> + <FileConfiguration Name="Debug|x64"> + <Tool Name="VCCustomBuildTool" + Description="Copying config.h from config.h.win32..." + CommandLine="$(CopyConfigH)" + Outputs="..\..\config.h" + /> + </FileConfiguration> + <FileConfiguration Name="Release|x64"> + <Tool Name="VCCustomBuildTool" + Description="Copying config.h from config.h.win32..." + CommandLine="$(CopyConfigH)" + Outputs="..\..\config.h" + /> + </FileConfiguration> + </File> + <File RelativePath="..\..\src\libcroco.symbols"> + <FileConfiguration Name="Debug|Win32"> + <Tool Name="VCCustomBuildTool" + Description="Generating libcroco.def..." + CommandLine="$(GenerateLibCrocoDef)" + Outputs="$(IntDir)\libcroco.def" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32"> + <Tool Name="VCCustomBuildTool" + Description="Generating libcroco.def..." + CommandLine="$(GenerateLibCrocoDef)" + Outputs="$(IntDir)\libcroco.def" + /> + </FileConfiguration> + <FileConfiguration Name="Debug|x64"> + <Tool Name="VCCustomBuildTool" + Description="Generating libcroco.def..." + CommandLine="$(GenerateLibCrocoDef)" + Outputs="$(IntDir)\libcroco.def" + /> + </FileConfiguration> + <FileConfiguration Name="Release|x64"> + <Tool Name="VCCustomBuildTool" + Description="Generating libcroco.def..." + CommandLine="$(GenerateLibCrocoDef)" + Outputs="$(IntDir)\libcroco.def" + /> + </FileConfiguration> + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/3rdparty/libcroco/win32/vs9/csslint.vcproj b/src/3rdparty/libcroco/win32/vs9/csslint.vcproj new file mode 100644 index 0000000..20ede16 --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/csslint.vcproj @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="big5"?> +<!-- +This file is part of The Croco Library +This program is free software; you can redistribute it and/or +modify it under the terms of version 2.1 of the GNU Lesser General Public +License as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA + +Author: Fan, Chun-wei +See COPYRIGHTS file for copyright information. +--> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="csslint" + ProjectGUID="{345080B1-9C5B-44B8-98D7-7381D50F3E13}" + RootNamespace="csslint" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + InheritedPropertySheets=".\croco-build-defines.vsprops" + ConfigurationType="1" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="_DEBUG" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + </Configuration> + <Configuration + Name="Release|Win32" + InheritedPropertySheets=".\croco-build-defines.vsprops" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + </Configuration> + <Configuration + Name="Debug|x64" + InheritedPropertySheets=".\croco-build-defines.vsprops" + ConfigurationType="1" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="_DEBUG" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="17" + /> + </Configuration> + <Configuration + Name="Release|x64" + InheritedPropertySheets=".\croco-build-defines.vsprops" + ConfigurationType="1" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="" + PreprocessorDefinitions="" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Sources" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File RelativePath="..\..\csslint\csslint.c" /> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/3rdparty/libcroco/win32/vs9/libcroco.sln b/src/3rdparty/libcroco/win32/vs9/libcroco.sln new file mode 100644 index 0000000..71e1b2f --- /dev/null +++ b/src/3rdparty/libcroco/win32/vs9/libcroco.sln @@ -0,0 +1,53 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croco", "croco.vcproj", "{4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csslint", "csslint.vcproj", "{345080B1-9C5B-44B8-98D7-7381D50F3E13}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA} = {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croco-install", "croco-install.vcproj", "{00702787-1566-484D-991F-4E7E459BB909}"
+ ProjectSection(ProjectDependencies) = postProject
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA} = {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13} = {345080B1-9C5B-44B8-98D7-7381D50F3E13}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|Win32.Build.0 = Debug|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|x64.ActiveCfg = Debug|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Debug|x64.Build.0 = Debug|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|Win32.ActiveCfg = Release|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|Win32.Build.0 = Release|Win32
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|x64.ActiveCfg = Release|x64
+ {4AFE9F9B-7F78-41A8-B066-C7CA89938ABA}.Release|x64.Build.0 = Release|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|Win32.ActiveCfg = Debug|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|Win32.Build.0 = Debug|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|x64.ActiveCfg = Debug|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Debug|x64.Build.0 = Debug|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|Win32.ActiveCfg = Release|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|Win32.Build.0 = Release|Win32
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|x64.ActiveCfg = Release|x64
+ {345080B1-9C5B-44B8-98D7-7381D50F3E13}.Release|x64.Build.0 = Release|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|Win32.ActiveCfg = Debug|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|Win32.Build.0 = Debug|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|x64.ActiveCfg = Debug|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Debug|x64.Build.0 = Debug|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|Win32.ActiveCfg = Release|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|Win32.Build.0 = Release|Win32
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|x64.ActiveCfg = Release|x64
+ {00702787-1566-484D-991F-4E7E459BB909}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
|