diff options
Diffstat (limited to 'csslint')
-rw-r--r-- | csslint/csslint.c | 383 |
1 files changed, 318 insertions, 65 deletions
diff --git a/csslint/csslint.c b/csslint/csslint.c index 1712f8b..87f5811 100644 --- a/csslint/csslint.c +++ b/csslint/csslint.c @@ -3,8 +3,7 @@ /* * csslint.c : a small tester program for CSS2 input * - * Copyright (C) 2002-2003 Gaël Chamoulaud <strider@freespiders.org> - * Dodji Seketeli <dodji@seketeli.org> + * Copyright (C) 2002-2003 Gaël Chamoulaud, 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 @@ -22,6 +21,7 @@ */ #include "libcroco.h" +#include <libxml/xpath.h> #include <glib.h> #include <string.h> @@ -37,21 +37,38 @@ struct Options gboolean show_version ; gboolean use_cssom ; gboolean display_help ; - gchar ** files_list ; + gboolean evaluate ; + gchar *author_sheet_path ; + gchar *user_sheet_path ; + gchar *ua_sheet_path ; + gchar *xml_path ; + gchar *xpath ; + gchar ** css_files_list ; }; -void -csslint_parse_cmd_line (int a_argc, char **a_argv, - struct Options *a_options); +static void +parse_cmd_line (int a_argc, char **a_argv, + struct Options *a_options); static void -csslint_show_version (const char *name); +display_version (void); static void -csslint_usage (const char *name); +display_usage (void); static enum CRStatus -csslint_cssom_parser_parse (guchar * a_file_uri); +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. @@ -59,9 +76,9 @@ csslint_cssom_parser_parse (guchar * a_file_uri); *@param the argv parameter of the main routine. *@param a_options out parameter the parsed options. */ -void -csslint_parse_cmd_line (int a_argc, char **a_argv, - struct Options *a_options) +static void +parse_cmd_line (int a_argc, char **a_argv, + struct Options *a_options) { int i= 0 ; @@ -69,7 +86,7 @@ csslint_parse_cmd_line (int a_argc, char **a_argv, if (a_argc <= 1) { - csslint_usage(a_argv[0]); + display_usage(); } for (i = 1 ; i < a_argc ; i++) @@ -77,29 +94,137 @@ csslint_parse_cmd_line (int a_argc, char **a_argv, if (a_argv[i][0] != '-') break ; if ((!strcmp (a_argv[i], "-version")) || - (!strcmp (a_argv[i], "--version"))) + (!strcmp (a_argv[i], "-v"))) { a_options->show_version = TRUE ; - } - if ((!strcmp (a_argv[i], "-cssom")) || - (!strcmp (a_argv[i], "--cssom"))) - { - a_options->use_cssom = TRUE ; - } - if (!strcmp (a_argv[i], "--help") || - !strcmp (a_argv[i], "-h")) + } + else if ( !strcmp (a_argv[i], "--evaluate") || + !strcmp (a_argv[i], "-e")) + { + gchar *xml_doc_path = NULL, + *author_sheet_path = NULL, + *user_sheet_path = NULL, + *ua_sheet_path = NULL ; + + for (i++ ; i < a_argc ; i++) + { + if (!strcmp (a_argv[i], "--author-sheet")) + { + if (author_sheet_path) + { + display_usage () ; + exit (-1); + } + author_sheet_path = a_argv[i] ; + 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 (user_sheet_path) + { + display_usage () ; + exit (-1); + } + user_sheet_path = a_argv[i] ; + 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] ; + i++ ; + } + else if (!strcmp (a_argv[i], "--ua-sheet")) + { + if (ua_sheet_path) + { + display_usage () ; + exit (-1); + } + ua_sheet_path = a_argv[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 expresion\n") ; + display_usage () ; + exit (-1); + } + a_options->xpath = a_argv[i] ; + } + else + { + break ; + } + } + if (!author_sheet_path && !user_sheet_path && !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], "--help") || + !strcmp (a_argv[i], "-h")) { a_options->display_help = TRUE ; } + else + { + display_usage () ; + exit (-1); + } } if (i >= a_argc) { - a_options->files_list = NULL ; + a_options->css_files_list = NULL ; } else { - a_options->files_list = &a_argv[i] ; + if (a_argv[i][0] == '-') + { + display_usage () ; + exit (-1) ; + } + a_options->css_files_list = &a_argv[i] ; } } @@ -109,17 +234,9 @@ csslint_parse_cmd_line (int a_argc, char **a_argv, *@param a_argv the argv variable passed to the main function. */ static void -csslint_show_version (const char *name) +display_version (void) { - fprintf(stderr, "%s: using libcroco version %s\n", name, LIBCROCO_VERSION); - fprintf(stderr, " compiled with: "); -#ifdef CROCO_HAVE_LIBXML2 - fprintf(stderr, "LIBXML2 "); -#endif - fprintf(stderr, "GLIB2 "); - fprintf(stderr, "SELENG "); - fprintf(stderr, "TESTS "); - fprintf(stderr, "\n"); + g_print ("%s\n", LIBCROCO_VERSION) ; } /** @@ -128,17 +245,11 @@ csslint_show_version (const char *name) *@param a_argv the argv variable passed to the main function. */ static void -csslint_usage(const char *name) +display_usage (void) { - printf("Usage : %s [options] CSS2files ...\n", name); - printf("\tParse the CSS2 files and output the result of the parsing\n"); - - /* Listing of different options */ - printf("\t--version : display the version of the CSS2 library used\n"); - printf("\t--cssom : parse a CSS file and builds a CSS object model\n"); - - printf("\nLibcroco project home page: http://www.freespiders.org/projects/libcroco\n"); - printf("To report bugs or get some help check: http://bugzilla.gnome.org/\n"); + g_print ("Usage: csslint <path to a css file>\n"); + g_print ("\t| csslint -v|--version\n") ; + g_print ("\t| csslint <--evaluate | -e> [--author-sheet <path> --user-sheet <path> --ua-sheet <path>\n] --xml <path> --xpath <xpath expression>") ; } /** @@ -151,7 +262,7 @@ csslint_usage(const char *name) *function, an error code otherwise. */ static enum CRStatus -csslint_cssom_parser_parse (guchar * a_file_uri) +cssom_parse (guchar * a_file_uri) { enum CRStatus status = CR_OK ; CROMParser *parser = NULL ; @@ -173,6 +284,153 @@ csslint_cssom_parser_parse (guchar * a_file_uri) 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) ; + return CR_ERROR ; + } + if (a_author_sheet_path) + { + status = cr_om_parser_simply_parse_file + (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 + (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 + (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 (!cascade) + { + g_printerr ("Could not instanciate the cascade\n") ; + return CR_ERROR ; + } + sel_eng = cr_sel_eng_new () ; + if (!sel_eng) + { + g_printerr ("Error: Could not instanciate the selection engine\n") ; + return CR_ERROR ; + } + xpath_context = xmlXPathNewContext (xml_doc) ; + if (!xpath_context) + { + g_printerr ("Error: Could not instanciate the xpath context\n") ; + return CR_ERROR ; + } + xpath_object = xmlXPathEvalExpression (a_xpath, + xpath_context) ; + if (!xpath_object) + { + g_printerr ("Error: Could not evaluate xpath expression\n") ; + return CR_ERROR ; + } + if (xpath_object->type != XPATH_NODESET || !xpath_object->nodesetval) + { + g_printerr ("Error: xpath does not evalualuate to a node set\n") ; + return CR_ERROR ; + } + + 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) ; + } + } + return CR_OK ; +} + int main (int argc, char **argv) { @@ -181,41 +439,36 @@ main (int argc, char **argv) memset (&options, 0, sizeof (struct Options)) ; options.use_cssom = TRUE ; - csslint_parse_cmd_line (argc, argv, &options); + parse_cmd_line (argc, argv, &options); if (options.show_version == TRUE) { - csslint_show_version(argv[0]); + display_version (); return 0; } if (options.display_help == TRUE) { - csslint_usage (argv[0]) ; + display_usage () ; return 0 ; } if (options.use_cssom == TRUE) { - if (options.files_list != NULL) + 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 = - csslint_cssom_parser_parse - (options.files_list[0]); + cssom_parse + (options.css_files_list[0]); } - else - { - csslint_usage (argv[0]); - return 0; - } - - if (status == CR_OK) - { - g_print ("\nOK\n"); - } - else - { - g_print ("\nKO\n"); - } } return 0; |