Revision: 1254 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1254&view=re... Author: ctabin Date: 2010-04-19 14:06:13 +0000 (Mon, 19 Apr 2010)
Log Message: ----------- keybindings added in xml pretty-printer (thx Frank)
Modified Paths: -------------- trunk/geany-plugins/pretty-printer/src/ConfigUI.c trunk/geany-plugins/pretty-printer/src/PluginEntry.c trunk/geany-plugins/pretty-printer/src/PluginEntry.h trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h
Modified: trunk/geany-plugins/pretty-printer/src/ConfigUI.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/ConfigUI.c 2010-04-18 09:45:35 UTC (rev 1253) +++ trunk/geany-plugins/pretty-printer/src/ConfigUI.c 2010-04-19 14:06:13 UTC (rev 1254) @@ -23,60 +23,60 @@
GtkWidget* createPrettyPrinterConfigUI(GtkDialog* dialog) { - //default printing options - if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } - - //TODO create configuration widget - - return NULL; + //default printing options + if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } + + //TODO create configuration widget + + return NULL; }
void saveSettings() { - //TODO save settings into a file + //TODO save settings into a file }
-/* -GtkWidget* plugin_configure(GtkDialog * dialog) +//Will never be used, just here for example +/*GtkWidget* plugin_configure(GtkDialog * dialog) { - //default printing options - if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } - - GtkWidget* globalBox = gtk_hbox_new(TRUE, 4); - GtkWidget* rightBox = gtk_vbox_new(FALSE, 6); - GtkWidget* centerBox = gtk_vbox_new(FALSE, 6); - GtkWidget* leftBox = gtk_vbox_new(FALSE, 6); - - GtkWidget* textLabel = gtk_label_new("Text nodes"); - GtkWidget* textOneLine = gtk_check_button_new_with_label("One line"); - GtkWidget* textInline = gtk_check_button_new_with_label("Inline"); - - GtkWidget* cdataLabel = gtk_label_new("CDATA nodes"); - GtkWidget* cdataOneLine = gtk_check_button_new_with_label("One line"); - GtkWidget* cdataInline = gtk_check_button_new_with_label("Inline"); - - GtkWidget* commentLabel = gtk_label_new("Comments"); - GtkWidget* commentOneLine = gtk_check_button_new_with_label("One line"); - GtkWidget* commentInline = gtk_check_button_new_with_label("Inline"); - - gtk_box_pack_start(GTK_BOX(globalBox), leftBox, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(globalBox), centerBox, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(globalBox), rightBox, FALSE, FALSE, 3); + //default printing options + if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } + + GtkWidget* globalBox = gtk_hbox_new(TRUE, 4); + GtkWidget* rightBox = gtk_vbox_new(FALSE, 6); + GtkWidget* centerBox = gtk_vbox_new(FALSE, 6); + GtkWidget* leftBox = gtk_vbox_new(FALSE, 6); + + GtkWidget* textLabel = gtk_label_new("Text nodes"); + GtkWidget* textOneLine = gtk_check_button_new_with_label("One line"); + GtkWidget* textInline = gtk_check_button_new_with_label("Inline"); + + GtkWidget* cdataLabel = gtk_label_new("CDATA nodes"); + GtkWidget* cdataOneLine = gtk_check_button_new_with_label("One line"); + GtkWidget* cdataInline = gtk_check_button_new_with_label("Inline"); + + GtkWidget* commentLabel = gtk_label_new("Comments"); + GtkWidget* commentOneLine = gtk_check_button_new_with_label("One line"); + GtkWidget* commentInline = gtk_check_button_new_with_label("Inline"); + + gtk_box_pack_start(GTK_BOX(globalBox), leftBox, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(globalBox), centerBox, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(globalBox), rightBox, FALSE, FALSE, 3);
- gtk_box_pack_start(GTK_BOX(leftBox), textLabel, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(centerBox), textOneLine, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(rightBox), textInline, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(leftBox), textLabel, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(centerBox), textOneLine, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(rightBox), textInline, FALSE, FALSE, 3);
- gtk_box_pack_start(GTK_BOX(leftBox), cdataLabel, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(centerBox), cdataOneLine, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(rightBox), cdataInline, FALSE, FALSE, 3); - - gtk_box_pack_start(GTK_BOX(leftBox), commentLabel, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(centerBox), commentOneLine, FALSE, FALSE, 3); - gtk_box_pack_start(GTK_BOX(rightBox), commentInline, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(leftBox), cdataLabel, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(centerBox), cdataOneLine, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(rightBox), cdataInline, FALSE, FALSE, 3); + + gtk_box_pack_start(GTK_BOX(leftBox), commentLabel, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(centerBox), commentOneLine, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(rightBox), commentInline, FALSE, FALSE, 3);
- gtk_widget_show_all(globalBox); - return globalBox; + gtk_widget_show_all(globalBox); + return globalBox; } */
Modified: trunk/geany-plugins/pretty-printer/src/PluginEntry.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/PluginEntry.c 2010-04-18 09:45:35 UTC (rev 1253) +++ trunk/geany-plugins/pretty-printer/src/PluginEntry.c 2010-04-19 14:06:13 UTC (rev 1254) @@ -25,9 +25,10 @@
//========================================== PLUGIN INFORMATION ==========================================================
-PLUGIN_VERSION_CHECK(130) -PLUGIN_SET_INFO("XML PrettyPrinter", "Formats an XML and makes it readable for human.", - "1.1", "Cédric Tabin - http://www.astorm.ch"); +PLUGIN_VERSION_CHECK(130); +PLUGIN_SET_INFO("XML PrettyPrinter", "Formats an XML and makes it human-readable.", + "1.11", "Cédric Tabin - http://www.astorm.ch"); +PLUGIN_KEY_GROUP(prettyprinter, 1);
//========================================== DECLARATIONS ================================================================
@@ -39,7 +40,7 @@
//declaration of the functions static void xml_format(GtkMenuItem *menuitem, gpointer gdata); -//static void config_closed(GtkWidget* configWidget, gint response, gpointer data); +static void kb_run_xml_pretty_print(G_GNUC_UNUSED guint key_id); void plugin_init(GeanyData *data); void plugin_cleanup(void);
@@ -57,6 +58,11 @@ gtk_widget_show(main_menu_item); gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu), main_menu_item);
+ //init keybindings + keybindings_set_item(plugin_key_group, 0, kb_run_xml_pretty_print, + 0, 0, "run_pretty_printer_xml", "Run the PrettyPrinter XML", + main_menu_item); + //add activation callback g_signal_connect(main_menu_item, "activate", G_CALLBACK(xml_format), NULL); } @@ -67,76 +73,85 @@ gtk_widget_destroy(main_menu_item); }
-//TODO uncomment when configuration widget ready -/*GtkWidget* plugin_configure(GtkDialog * dialog) -{ - //creates the configuration widget - GtkWidget* widget = createPrettyPrinterConfigUI(dialog); - g_signal_connect(dialog, "response", G_CALLBACK(config_closed), NULL); - return widget; -}*/ +#ifdef PLUGIN_XMLPP_GUI + static void config_closed(GtkWidget* configWidget, gint response, gpointer data);
+ GtkWidget* plugin_configure(GtkDialog * dialog) + { + //creates the configuration widget + GtkWidget* widget = createPrettyPrinterConfigUI(dialog); + g_signal_connect(dialog, "response", G_CALLBACK(config_closed), NULL); + return widget; + } + //========================================== LISTENERS ===================================================================
-//TODO uncomment when configuration widget ready -/*void config_closed(GtkWidget* configWidget, gint response, gpointer gdata) + void config_closed(GtkWidget* configWidget, gint response, gpointer gdata) + { + //if the user clicked OK or APPLY, then save the settings + if (response == GTK_RESPONSE_OK || + response == GTK_RESPONSE_APPLY) + { + saveSettings(); + } + } +#endif + +static void kb_run_xml_pretty_print(G_GNUC_UNUSED guint key_id) { - //if the user clicked OK or APPLY, then save the settings - if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) - { - saveSettings(); - } -}*/ + xml_format(NULL, NULL); +}
-void xml_format(GtkMenuItem* menuitem, gpointer gdata) +static void xml_format(GtkMenuItem* menuitem, gpointer gdata) { - //retrieves the current document - GeanyDocument* doc = document_get_current(); - GeanyEditor* editor = doc->editor; - ScintillaObject* sco = editor->sci; + //retrieves the current document + GeanyDocument* doc = document_get_current(); + g_return_if_fail(doc != NULL); + + GeanyEditor* editor = doc->editor; + ScintillaObject* sco = editor->sci;
- g_return_if_fail(doc != NULL); + //default printing options + if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); }
- //default printing options - if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } + //prepare the buffer that will contain the text + //from the scintilla object + int length = sci_get_length(sco)+1; + char* buffer = (char*)malloc(length*sizeof(char)); + if (buffer == NULL) { exit(-1); } //malloc error
- //prepare the buffer that will contain the text - //from the scintilla object - int length = sci_get_length(sco)+1; - char* buffer = (char*)malloc(length*sizeof(char)); - if (buffer == NULL) { exit(-1); } //malloc error + //retrieves the text + sci_get_text(sco, length, buffer);
- //retrieves the text - sci_get_text(sco, length, buffer); + //checks if the data is an XML format + xmlDoc* xmlDoc = xmlParseDoc((unsigned char*)buffer);
- //checks if the data is an XML format - xmlDoc* xmlDoc = xmlParseDoc((unsigned char*)buffer); + //this is not a valid xml => exit with an error message + if(xmlDoc == NULL) + { + dialogs_show_msgbox(GTK_MESSAGE_ERROR, "Unable to parse the content as XML."); + return; + }
- if(xmlDoc == NULL) //this is not a valid xml - { - dialogs_show_msgbox(GTK_MESSAGE_ERROR, "Unable to parse the content as XML."); - return; - } + //process pretty-printing + int result = processXMLPrettyPrinting(&buffer, &length, prettyPrintingOptions); + if (result != PRETTY_PRINTING_SUCCESS) + { + dialogs_show_msgbox(GTK_MESSAGE_ERROR, "Unable to process PrettyPrinting on the specified XML because some features are not supported.\n\nSee Help > Debug messages for more details..."); + return; + }
- //process pretty-printing - int result = processXMLPrettyPrinting(&buffer, &length, prettyPrintingOptions); - if (result != 0) - { - dialogs_show_msgbox(GTK_MESSAGE_ERROR, "Unable to process PrettyPrinting on the specified XML because some features are not supported.\n\nSee Help > Debug messages for more details..."); - return; - } + //updates the document + sci_set_text(sco, buffer);
- //updates the document - sci_set_text(sco, buffer); + //set the line + int xOffset = scintilla_send_message(sco, SCI_GETXOFFSET, 0, 0); + scintilla_send_message(sco, SCI_LINESCROLL, -xOffset, 0); //TODO update with the right function-call for geany-0.19
- //set the line - int xOffset = scintilla_send_message(sco, SCI_GETXOFFSET, 0, 0); - scintilla_send_message(sco, SCI_LINESCROLL, -xOffset, 0); //TODO update with the right function-call for geany-0.19 + //sets the type + GeanyFiletype* fileType = filetypes_index(GEANY_FILETYPES_XML); + document_set_filetype(doc, fileType);
- //sets the type - GeanyFiletype* fileType = filetypes_index(GEANY_FILETYPES_XML); - document_set_filetype(doc, fileType); - - //free all - xmlFreeDoc(xmlDoc); + //free all + xmlFreeDoc(xmlDoc); }
Modified: trunk/geany-plugins/pretty-printer/src/PluginEntry.h =================================================================== --- trunk/geany-plugins/pretty-printer/src/PluginEntry.h 2010-04-18 09:45:35 UTC (rev 1253) +++ trunk/geany-plugins/pretty-printer/src/PluginEntry.h 2010-04-19 14:06:13 UTC (rev 1254) @@ -16,10 +16,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
-//TODO is this header really useful ? #ifndef PLUGIN_ENTRY_H #define PLUGIN_ENTRY_H
+// This constants will be enabled once the preferences GUI will be finished :) +//#define PLUGIN_XMLPP_GUI + //========================================== INCLUDES ==========================================================
#include <stdlib.h>
Modified: trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c 2010-04-18 09:45:35 UTC (rev 1253) +++ trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c 2010-04-19 14:06:13 UTC (rev 1254) @@ -21,320 +21,320 @@ //======================= FUNCTIONS ====================================================================
//xml pretty printing functions -static void putCharInBuffer(char charToAdd); //put a char into the new char buffer -static void putCharsInBuffer(char* charsToAdd); //put the chars into the new char buffer -static void putNextCharsInBuffer(int nbChars); //put the next nbChars of the input buffer into the new buffer -static int readWhites(); //read the next whites into the input buffer -static char readNextChar(); //read the next char into the input buffer; -static char getNextChar(); //returns the next char but do not increase the input buffer index (use readNextChar for that) -static char getPreviousInsertedChar(); //returns the last inserted char into the new buffer -static gboolean isWhite(char c); //check if the specified char is a white -static gboolean isLineBreak(char c); //check if the specified char is a new line -static gboolean isQuote(char c); //check if the specified char is a quote (simple or double) -static int putNewLine(); //put a new line into the new char buffer with the correct number of whites (indentation) -static gboolean isInlineNodeAllowed(); //check if it is possible to have an inline node -static void resetBackwardIndentation(gboolean resetLineBreak); //reset the indentation for the current depth (just reset the index in fact) +static void putCharInBuffer(char charToAdd); //put a char into the new char buffer +static void putCharsInBuffer(char* charsToAdd); //put the chars into the new char buffer +static void putNextCharsInBuffer(int nbChars); //put the next nbChars of the input buffer into the new buffer +static int readWhites(); //read the next whites into the input buffer +static char readNextChar(); //read the next char into the input buffer; +static char getNextChar(); //returns the next char but do not increase the input buffer index (use readNextChar for that) +static char getPreviousInsertedChar(); //returns the last inserted char into the new buffer +static gboolean isWhite(char c); //check if the specified char is a white +static gboolean isLineBreak(char c); //check if the specified char is a new line +static gboolean isQuote(char c); //check if the specified char is a quote (simple or double) +static int putNewLine(); //put a new line into the new char buffer with the correct number of whites (indentation) +static gboolean isInlineNodeAllowed(); //check if it is possible to have an inline node +static void resetBackwardIndentation(gboolean resetLineBreak); //reset the indentation for the current depth (just reset the index in fact)
//specific parsing functions -static int processElements(); //returns the number of elements processed -static void processElementAttribute(); //process on attribute of a node -static void processElementAttributes(); //process all the attributes of a node -static void processHeader(); //process the header <?xml version="..." ?> -static void processNode(); //process an XML node -static void processTextNode(); //process a text node -static void processComment(); //process a comment -static void processCDATA(); //process a CDATA node -static void processDoctype(); //process a DOCTYPE node -static void processDoctypeElement(); //process a DOCTYPE ELEMENT node +static int processElements(); //returns the number of elements processed +static void processElementAttribute(); //process on attribute of a node +static void processElementAttributes(); //process all the attributes of a node +static void processHeader(); //process the header <?xml version="..." ?> +static void processNode(); //process an XML node +static void processTextNode(); //process a text node +static void processComment(); //process a comment +static void processCDATA(); //process a CDATA node +static void processDoctype(); //process a DOCTYPE node +static void processDoctypeElement(); //process a DOCTYPE ELEMENT node
//debug function -static void printError(char *msg, ...); //just print a message like the printf method -static void printDebugStatus(); //just print some variables into the console for debugging +static void printError(char *msg, ...); //just print a message like the printf method +static void printDebugStatus(); //just print some variables into the console for debugging
//============================================ PRIVATE PROPERTIES ======================================
//those are variables that are shared by the functions and //shouldn't be altered.
-static int result; //result of the pretty printing -static char* xmlPrettyPrinted; //new buffer for the formatted XML -static int xmlPrettyPrintedLength; //buffer size -static int xmlPrettyPrintedIndex; //buffer index (position of the next char to insert) -static char* inputBuffer; //input buffer -static int inputBufferLength; //input buffer size -static int inputBufferIndex; //input buffer index (position of the next char to read into the input string) -static int currentDepth; //current depth (for indentation) -static char* currentNodeName; //current node name -static gboolean appendIndentation; //if the indentation must be added (with a line break before) -static gboolean lastNodeOpen; //defines if the last action was a not opening or not -static PrettyPrintingOptions* options; //options of PrettyPrinting +static int result; //result of the pretty printing +static char* xmlPrettyPrinted; //new buffer for the formatted XML +static int xmlPrettyPrintedLength; //buffer size +static int xmlPrettyPrintedIndex; //buffer index (position of the next char to insert) +static char* inputBuffer; //input buffer +static int inputBufferLength; //input buffer size +static int inputBufferIndex; //input buffer index (position of the next char to read into the input string) +static int currentDepth; //current depth (for indentation) +static char* currentNodeName; //current node name +static gboolean appendIndentation; //if the indentation must be added (with a line break before) +static gboolean lastNodeOpen; //defines if the last action was a not opening or not +static PrettyPrintingOptions* options; //options of PrettyPrinting
//============================================ GENERAL FUNCTIONS =======================================
int processXMLPrettyPrinting(char** buffer, int* length, PrettyPrintingOptions* ppOptions) { - //empty buffer, nothing to process - if (*length == 0) { return PRETTY_PRINTING_EMPTY_XML; } - if (buffer == NULL || *buffer == NULL) { return PRETTY_PRINTING_EMPTY_XML; } - - //initialize the variables - result = PRETTY_PRINTING_SUCCESS; - gboolean freeOptions = FALSE; - if (ppOptions == NULL) { ppOptions = createDefaultPrettyPrintingOptions(); freeOptions = TRUE; } - options = ppOptions; - - currentNodeName = NULL; - appendIndentation = FALSE; - lastNodeOpen = FALSE; - xmlPrettyPrintedIndex = 0; - inputBufferIndex = 0; - currentDepth = -1; - - inputBuffer = *buffer; - inputBufferLength = *length; - - xmlPrettyPrintedLength = *length; - xmlPrettyPrinted = (char*)malloc(sizeof(char)*(*length)); - if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } - - //go to the first char - readWhites(); + //empty buffer, nothing to process + if (*length == 0) { return PRETTY_PRINTING_EMPTY_XML; } + if (buffer == NULL || *buffer == NULL) { return PRETTY_PRINTING_EMPTY_XML; } + + //initialize the variables + result = PRETTY_PRINTING_SUCCESS; + gboolean freeOptions = FALSE; + if (ppOptions == NULL) { ppOptions = createDefaultPrettyPrintingOptions(); freeOptions = TRUE; } + options = ppOptions; + + currentNodeName = NULL; + appendIndentation = FALSE; + lastNodeOpen = FALSE; + xmlPrettyPrintedIndex = 0; + inputBufferIndex = 0; + currentDepth = -1; + + inputBuffer = *buffer; + inputBufferLength = *length; + + xmlPrettyPrintedLength = *length; + xmlPrettyPrinted = (char*)malloc(sizeof(char)*(*length)); + if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } + + //go to the first char + readWhites();
- //process the pretty-printing - processElements(); - - //close the buffer - putCharInBuffer('\0'); - - //adjust the final size - xmlPrettyPrinted = realloc(xmlPrettyPrinted, xmlPrettyPrintedIndex); - if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } - - //freeing the unused values - if (freeOptions) { free(options); } - - //if success, then update the values - if (result == PRETTY_PRINTING_SUCCESS) - { - free(*buffer); - *buffer = xmlPrettyPrinted; - *length = xmlPrettyPrintedIndex-2; //the '\0' is not in the length - } - //else clean the other values - else - { - free(xmlPrettyPrinted); - } - - //updating the pointers for the using into the caller function - xmlPrettyPrinted = NULL; //avoid reference - inputBuffer = NULL; //avoid reference - currentNodeName = NULL; //avoid reference - options = NULL; //avoid reference - - //and finally the result - return result; + //process the pretty-printing + processElements(); + + //close the buffer + putCharInBuffer('\0'); + + //adjust the final size + xmlPrettyPrinted = realloc(xmlPrettyPrinted, xmlPrettyPrintedIndex); + if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } + + //freeing the unused values + if (freeOptions) { free(options); } + + //if success, then update the values + if (result == PRETTY_PRINTING_SUCCESS) + { + free(*buffer); + *buffer = xmlPrettyPrinted; + *length = xmlPrettyPrintedIndex-2; //the '\0' is not in the length + } + //else clean the other values + else + { + free(xmlPrettyPrinted); + } + + //updating the pointers for the using into the caller function + xmlPrettyPrinted = NULL; //avoid reference + inputBuffer = NULL; //avoid reference + currentNodeName = NULL; //avoid reference + options = NULL; //avoid reference + + //and finally the result + return result; }
PrettyPrintingOptions* createDefaultPrettyPrintingOptions() { - PrettyPrintingOptions* options = (PrettyPrintingOptions*)malloc(sizeof(PrettyPrintingOptions)); - if (options == NULL) - { - g_error("Unable to allocate memory for PrettyPrintingOptions"); - return NULL; - } - - options->newLineChars = "\r\n"; - options->indentChar = ' '; - options->indentLength = 2; - options->oneLineText = TRUE; - options->inlineText = TRUE; - options->oneLineComment = TRUE; - options->inlineComment = TRUE; - options->oneLineCdata = TRUE; - options->inlineCdata = TRUE; - options->emptyNodeStripping = TRUE; - options->emptyNodeStrippingSpace = TRUE; - options->forceEmptyNodeSplit = FALSE; - options->trimLeadingWhites = TRUE; - options->trimTrailingWhites = TRUE; - - return options; + PrettyPrintingOptions* options = (PrettyPrintingOptions*)malloc(sizeof(PrettyPrintingOptions)); + if (options == NULL) + { + g_error("Unable to allocate memory for PrettyPrintingOptions"); + return NULL; + } + + options->newLineChars = "\r\n"; + options->indentChar = ' '; + options->indentLength = 2; + options->oneLineText = TRUE; + options->inlineText = TRUE; + options->oneLineComment = TRUE; + options->inlineComment = TRUE; + options->oneLineCdata = TRUE; + options->inlineCdata = TRUE; + options->emptyNodeStripping = TRUE; + options->emptyNodeStrippingSpace = TRUE; + options->forceEmptyNodeSplit = FALSE; + options->trimLeadingWhites = TRUE; + options->trimTrailingWhites = TRUE; + + return options; }
void putNextCharsInBuffer(int nbChars) { - int i; - for (i=0 ; i<nbChars ; ++i) - { - char c = readNextChar(); - putCharInBuffer(c); - } + int i; + for (i=0 ; i<nbChars ; ++i) + { + char c = readNextChar(); + putCharInBuffer(c); + } }
void putCharInBuffer(char charToAdd) { - //check if the buffer is full and reallocation if needed - if (xmlPrettyPrintedIndex >= xmlPrettyPrintedLength) - { - if (charToAdd == '\0') { ++xmlPrettyPrintedLength; } - else { xmlPrettyPrintedLength += inputBufferLength; } - xmlPrettyPrinted = (char*)realloc(xmlPrettyPrinted, xmlPrettyPrintedLength); - if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } - } - - //putting the char and increase the index for the next one - xmlPrettyPrinted[xmlPrettyPrintedIndex] = charToAdd; - ++xmlPrettyPrintedIndex; + //check if the buffer is full and reallocation if needed + if (xmlPrettyPrintedIndex >= xmlPrettyPrintedLength) + { + if (charToAdd == '\0') { ++xmlPrettyPrintedLength; } + else { xmlPrettyPrintedLength += inputBufferLength; } + xmlPrettyPrinted = (char*)realloc(xmlPrettyPrinted, xmlPrettyPrintedLength); + if (xmlPrettyPrinted == NULL) { g_error("Allocation error"); } + } + + //putting the char and increase the index for the next one + xmlPrettyPrinted[xmlPrettyPrintedIndex] = charToAdd; + ++xmlPrettyPrintedIndex; }
void putCharsInBuffer(char* charsToAdd) { - int index = 0; - while (charsToAdd[index] != '\0') - { - putCharInBuffer(charsToAdd[index]); - ++index; - } + int index = 0; + while (charsToAdd[index] != '\0') + { + putCharInBuffer(charsToAdd[index]); + ++index; + } }
char getPreviousInsertedChar() { - return xmlPrettyPrinted[xmlPrettyPrintedIndex-1]; + return xmlPrettyPrinted[xmlPrettyPrintedIndex-1]; }
int putNewLine() { - putCharsInBuffer(options->newLineChars); - int spaces = currentDepth*options->indentLength; - int i; - for(i=0 ; i<spaces ; ++i) - { - putCharInBuffer(options->indentChar); - } - - return spaces; + putCharsInBuffer(options->newLineChars); + int spaces = currentDepth*options->indentLength; + int i; + for(i=0 ; i<spaces ; ++i) + { + putCharInBuffer(options->indentChar); + } + + return spaces; }
char getNextChar() { - return inputBuffer[inputBufferIndex]; + return inputBuffer[inputBufferIndex]; }
char readNextChar() -{ - return inputBuffer[inputBufferIndex++]; +{ + return inputBuffer[inputBufferIndex++]; }
int readWhites() { - int counter = 0; - while(isWhite(inputBuffer[inputBufferIndex])) - { - ++counter; - ++inputBufferIndex; - } - - return counter; + int counter = 0; + while(isWhite(inputBuffer[inputBufferIndex])) + { + ++counter; + ++inputBufferIndex; + } + + return counter; }
gboolean isQuote(char c) { - if (c == ''') return TRUE; - if (c == '"') return TRUE; - - return FALSE; + if (c == ''') return TRUE; + if (c == '"') return TRUE; + + return FALSE; }
gboolean isWhite(char c) { - if (c == ' ') return TRUE; - if (c == '\t') return TRUE; - if (c == '\r') return TRUE; - if (c == '\n') return TRUE; + if (c == ' ') return TRUE; + if (c == '\t') return TRUE; + if (c == '\r') return TRUE; + if (c == '\n') return TRUE;
- return FALSE; + return FALSE; }
gboolean isLineBreak(char c) { - if (c == '\n') return TRUE; - if (c == '\r') return TRUE; - - return FALSE; + if (c == '\n') return TRUE; + if (c == '\r') return TRUE; + + return FALSE; }
gboolean isInlineNodeAllowed() { - //the last action was not an opening => inline not allowed - if (!lastNodeOpen) { return FALSE; } - - int firstChar = getNextChar(); //should be '<' or we are in a text node - int secondChar = inputBuffer[inputBufferIndex+1]; //should be '!' - int thirdChar = inputBuffer[inputBufferIndex+2]; //should be '-' or '[' - - int index = inputBufferIndex+1; - if (firstChar == '<') - { - //another node is being open ==> no inline ! - if (secondChar != '!') { return FALSE; } - - //okay we are in a comment node, so read until it is closed - - //select the closing char - char closingComment = '-'; - if (thirdChar == '[') { closingComment = ']'; } - - //read until closing - char oldChar = ' '; - index += 3; //that by pass meanless chars - gboolean loop = TRUE; - while (loop) - { - char current = inputBuffer[index]; - if (current == closingComment && oldChar == closingComment) { loop = FALSE; } //end of comment - oldChar = current; - ++index; - } - - //okay now avoid blanks - // inputBuffer[index] is now '>' - ++index; - while (isWhite(inputBuffer[index])) { ++index; } - } - else - { - //this is a text node. Simply loop to the next '<' - while (inputBuffer[index] != '<') { ++index; } - } - - //check what do we have now - char currentChar = inputBuffer[index]; - if (currentChar == '<') - { - //check if that is a closing node - currentChar = inputBuffer[index+1]; - if (currentChar == '/') - { - //as we are in a correct XML (so far...), if the node is - //being directly close, the inline is allowed !!! - return TRUE; - } - } - - //inline not allowed... - return FALSE; + //the last action was not an opening => inline not allowed + if (!lastNodeOpen) { return FALSE; } + + int firstChar = getNextChar(); //should be '<' or we are in a text node + int secondChar = inputBuffer[inputBufferIndex+1]; //should be '!' + int thirdChar = inputBuffer[inputBufferIndex+2]; //should be '-' or '[' + + int index = inputBufferIndex+1; + if (firstChar == '<') + { + //another node is being open ==> no inline ! + if (secondChar != '!') { return FALSE; } + + //okay we are in a comment node, so read until it is closed + + //select the closing char + char closingComment = '-'; + if (thirdChar == '[') { closingComment = ']'; } + + //read until closing + char oldChar = ' '; + index += 3; //that by pass meanless chars + gboolean loop = TRUE; + while (loop) + { + char current = inputBuffer[index]; + if (current == closingComment && oldChar == closingComment) { loop = FALSE; } //end of comment + oldChar = current; + ++index; + } + + //okay now avoid blanks + // inputBuffer[index] is now '>' + ++index; + while (isWhite(inputBuffer[index])) { ++index; } + } + else + { + //this is a text node. Simply loop to the next '<' + while (inputBuffer[index] != '<') { ++index; } + } + + //check what do we have now + char currentChar = inputBuffer[index]; + if (currentChar == '<') + { + //check if that is a closing node + currentChar = inputBuffer[index+1]; + if (currentChar == '/') + { + //as we are in a correct XML (so far...), if the node is + //being directly close, the inline is allowed !!! + return TRUE; + } + } + + //inline not allowed... + return FALSE; }
void resetBackwardIndentation(gboolean resetLineBreak) { - xmlPrettyPrintedIndex -= (currentDepth*options->indentLength); - if (resetLineBreak) - { - int len = strlen(options->newLineChars); - xmlPrettyPrintedIndex -= len; - } + xmlPrettyPrintedIndex -= (currentDepth*options->indentLength); + if (resetLineBreak) + { + int len = strlen(options->newLineChars); + xmlPrettyPrintedIndex -= len; + } }
//######################################################################################################################################### @@ -349,567 +349,567 @@
int processElements() { - int counter = 0; - ++currentDepth; - gboolean loop = TRUE; - while (loop && result == PRETTY_PRINTING_SUCCESS) - { - //strip unused whites - readWhites(); - - char nextChar = getNextChar(); - if (nextChar == '\0') { return 0; } //no more data to read - - //put a new line with indentation - if (appendIndentation) { putNewLine(); } - - //always append indentation (but need to store the state) - gboolean indentBackward = appendIndentation; - appendIndentation = TRUE; - - //okay what do we have now ? - if (nextChar != '<') - { - //a simple text node - processTextNode(); - ++counter; - } - else //some more check are needed - { - nextChar = inputBuffer[inputBufferIndex+1]; - if (nextChar == '!') - { - char oneMore = inputBuffer[inputBufferIndex+2]; - if (oneMore == '-') { processComment(); ++counter; } //a comment - else if (oneMore == '[') { processCDATA(); ++counter; } //cdata - else if (oneMore == 'D') { processDoctype(); ++counter; } //doctype <!DOCTYPE ... > - else if (oneMore == 'E') { processDoctypeElement(); ++counter; } //doctype element <!ELEMENT ... > - else - { - printError("processElements : Invalid char '%c' afer '<!'", oneMore); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - } - } - else if (nextChar == '/') - { - //close a node => stop the loop !! - loop = FALSE; - if (indentBackward) - { - //INDEX HACKING - xmlPrettyPrintedIndex -= options->indentLength; - } - } - else if (nextChar == '?') - { - //this is a header - processHeader(); - } - else - { - //a new node is open - processNode(); - ++counter; - } - } - } - - --currentDepth; - return counter; + int counter = 0; + ++currentDepth; + gboolean loop = TRUE; + while (loop && result == PRETTY_PRINTING_SUCCESS) + { + //strip unused whites + readWhites(); + + char nextChar = getNextChar(); + if (nextChar == '\0') { return 0; } //no more data to read + + //put a new line with indentation + if (appendIndentation) { putNewLine(); } + + //always append indentation (but need to store the state) + gboolean indentBackward = appendIndentation; + appendIndentation = TRUE; + + //okay what do we have now ? + if (nextChar != '<') + { + //a simple text node + processTextNode(); + ++counter; + } + else //some more check are needed + { + nextChar = inputBuffer[inputBufferIndex+1]; + if (nextChar == '!') + { + char oneMore = inputBuffer[inputBufferIndex+2]; + if (oneMore == '-') { processComment(); ++counter; } //a comment + else if (oneMore == '[') { processCDATA(); ++counter; } //cdata + else if (oneMore == 'D') { processDoctype(); ++counter; } //doctype <!DOCTYPE ... > + else if (oneMore == 'E') { processDoctypeElement(); ++counter; } //doctype element <!ELEMENT ... > + else + { + printError("processElements : Invalid char '%c' afer '<!'", oneMore); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + } + } + else if (nextChar == '/') + { + //close a node => stop the loop !! + loop = FALSE; + if (indentBackward) + { + //INDEX HACKING + xmlPrettyPrintedIndex -= options->indentLength; + } + } + else if (nextChar == '?') + { + //this is a header + processHeader(); + } + else + { + //a new node is open + processNode(); + ++counter; + } + } + } + + --currentDepth; + return counter; }
void processElementAttribute() { - //process the attribute name - char nextChar = readNextChar(); - while (nextChar != '=') - { - putCharInBuffer(nextChar); - nextChar = readNextChar(); - } - - putCharInBuffer(nextChar); //that's the '=' - - //read the simple quote or double quote and put it into the buffer - char quote = readNextChar(); - putCharInBuffer(quote); - - //process until the last quote - char value = readNextChar(); - while(value != quote) - { - putCharInBuffer(value); - value = readNextChar(); - } - - //simply add the last quote - putCharInBuffer(quote); + //process the attribute name + char nextChar = readNextChar(); + while (nextChar != '=') + { + putCharInBuffer(nextChar); + nextChar = readNextChar(); + } + + putCharInBuffer(nextChar); //that's the '=' + + //read the simple quote or double quote and put it into the buffer + char quote = readNextChar(); + putCharInBuffer(quote); + + //process until the last quote + char value = readNextChar(); + while(value != quote) + { + putCharInBuffer(value); + value = readNextChar(); + } + + //simply add the last quote + putCharInBuffer(quote); }
void processElementAttributes() { - char current = getNextChar(); //should not be a white - if (isWhite(current)) - { - printError("processElementAttributes : first char shouldn't be a white"); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - - gboolean loop = TRUE; - while (loop) - { - readWhites(); //strip the whites - - char next = getNextChar(); //don't read the last char (processed afterwards) - if (next == '/') { loop = FALSE; } /* end of node */ - else if (next == '>') { loop = FALSE; } /* end of tag */ - else if (next == '?') { loop = FALSE; } /* end of header */ - else - { - putCharInBuffer(' '); //put only one space to separate attributes - processElementAttribute(); - } - } + char current = getNextChar(); //should not be a white + if (isWhite(current)) + { + printError("processElementAttributes : first char shouldn't be a white"); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + + gboolean loop = TRUE; + while (loop) + { + readWhites(); //strip the whites + + char next = getNextChar(); //don't read the last char (processed afterwards) + if (next == '/') { loop = FALSE; } /* end of node */ + else if (next == '>') { loop = FALSE; } /* end of tag */ + else if (next == '?') { loop = FALSE; } /* end of header */ + else + { + putCharInBuffer(' '); //put only one space to separate attributes + processElementAttribute(); + } + } }
void processHeader() { - int firstChar = inputBuffer[inputBufferIndex]; //should be '<' - int secondChar = inputBuffer[inputBufferIndex+1]; //must be '?' - - if (firstChar != '<') - { - /* what ?????? invalid xml !!! */ - printError("processHeader : first char should be '<' (not '%c')", firstChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; return; - } - - if (secondChar == '?') - { - //puts the '<' and '?' chars into the new buffer - putNextCharsInBuffer(2); - - while(!isWhite(getNextChar())) { putNextCharsInBuffer(1); } - - readWhites(); - processElementAttributes(); - - //puts the '?' and '>' chars into the new buffer - putNextCharsInBuffer(2); - } + int firstChar = inputBuffer[inputBufferIndex]; //should be '<' + int secondChar = inputBuffer[inputBufferIndex+1]; //must be '?' + + if (firstChar != '<') + { + /* what ?????? invalid xml !!! */ + printError("processHeader : first char should be '<' (not '%c')", firstChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; return; + } + + if (secondChar == '?') + { + //puts the '<' and '?' chars into the new buffer + putNextCharsInBuffer(2); + + while(!isWhite(getNextChar())) { putNextCharsInBuffer(1); } + + readWhites(); + processElementAttributes(); + + //puts the '?' and '>' chars into the new buffer + putNextCharsInBuffer(2); + } }
void processNode() { - int opening = readNextChar(); - if (opening != '<') - { - printError("processNode : The first char should be '<' (not '%c')", opening); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - - putCharInBuffer(opening); - - //read the node name - int nodeNameLength = 0; - while (!isWhite(getNextChar()) && - getNextChar() != '>' && //end of the tag - getNextChar() != '/') //tag is being closed - { - putNextCharsInBuffer(1); - ++nodeNameLength; - } + int opening = readNextChar(); + if (opening != '<') + { + printError("processNode : The first char should be '<' (not '%c')", opening); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + + putCharInBuffer(opening); + + //read the node name + int nodeNameLength = 0; + while (!isWhite(getNextChar()) && + getNextChar() != '>' && //end of the tag + getNextChar() != '/') //tag is being closed + { + putNextCharsInBuffer(1); + ++nodeNameLength; + }
- //store the name - char* nodeName = (char*)malloc(sizeof(char)*nodeNameLength+1); - if (nodeName == NULL) { g_error("Allocation error"); } - nodeName[nodeNameLength] = '\0'; - int i; - for (i=0 ; i<nodeNameLength ; ++i) - { - int index = xmlPrettyPrintedIndex-nodeNameLength+i; - nodeName[i] = xmlPrettyPrinted[index]; - } - - currentNodeName = nodeName; //set the name for using in other methods - lastNodeOpen = TRUE; + //store the name + char* nodeName = (char*)malloc(sizeof(char)*nodeNameLength+1); + if (nodeName == NULL) { g_error("Allocation error"); } + nodeName[nodeNameLength] = '\0'; + int i; + for (i=0 ; i<nodeNameLength ; ++i) + { + int index = xmlPrettyPrintedIndex-nodeNameLength+i; + nodeName[i] = xmlPrettyPrinted[index]; + } + + currentNodeName = nodeName; //set the name for using in other methods + lastNodeOpen = TRUE;
- //process the attributes - readWhites(); - processElementAttributes(); - - //process the end of the tag - int subElementsProcessed = 0; - char nextChar = getNextChar(); //should be either '/' or '>' - if (nextChar == '/') //the node is being closed immediatly - { - //closing node directly - if (options->emptyNodeStripping || !options->forceEmptyNodeSplit) - { - if (options->emptyNodeStrippingSpace) { putCharInBuffer(' '); } - putNextCharsInBuffer(2); - } - //split the closing nodes - else - { - readNextChar(); //removing '/' - readNextChar(); //removing '>' - - putCharInBuffer('>'); - if (!options->inlineText) - { - //no inline text => new line ! - putNewLine(); - } - - putCharsInBuffer("</"); - putCharsInBuffer(currentNodeName); - putCharInBuffer('>'); - } - - lastNodeOpen=FALSE; - return; - } - else if (nextChar == '>') - { - //the tag is just closed (maybe some content) - putNextCharsInBuffer(1); - subElementsProcessed = processElements(TRUE); - } - else - { - printError("processNode : Invalid character '%c'", nextChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - - //if the code reaches this area, then the processElements has been called and we must - //close the opening tag - char closeChar = getNextChar(); - if (closeChar != '<') - { - printError("processNode : Invalid character '%c' for closing tag (should be '<')", closeChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - - do - { - closeChar = readNextChar(); - putCharInBuffer(closeChar); - } - while(closeChar != '>'); - - //there is no elements - if (subElementsProcessed == 0) - { - //the node will be stripped - if (options->emptyNodeStripping) - { - //because we have '<nodeName ...></nodeName>' - xmlPrettyPrintedIndex -= nodeNameLength+4; - resetBackwardIndentation(TRUE); - - if (options->emptyNodeStrippingSpace) { putCharInBuffer(' '); } - putCharsInBuffer("/>"); - } - //the closing tag will be put on the same line - else if (options->inlineText) - { - //correct the index because we have '</nodeName>' - xmlPrettyPrintedIndex -= nodeNameLength+3; - resetBackwardIndentation(TRUE); - - //rewrite the node name - putCharsInBuffer("</"); - putCharsInBuffer(currentNodeName); - putCharInBuffer('>'); - } - } - - //the node is closed - lastNodeOpen = FALSE; - - //freeeeeeee !!! - free(nodeName); - nodeName = NULL; - currentNodeName = NULL; + //process the attributes + readWhites(); + processElementAttributes(); + + //process the end of the tag + int subElementsProcessed = 0; + char nextChar = getNextChar(); //should be either '/' or '>' + if (nextChar == '/') //the node is being closed immediatly + { + //closing node directly + if (options->emptyNodeStripping || !options->forceEmptyNodeSplit) + { + if (options->emptyNodeStrippingSpace) { putCharInBuffer(' '); } + putNextCharsInBuffer(2); + } + //split the closing nodes + else + { + readNextChar(); //removing '/' + readNextChar(); //removing '>' + + putCharInBuffer('>'); + if (!options->inlineText) + { + //no inline text => new line ! + putNewLine(); + } + + putCharsInBuffer("</"); + putCharsInBuffer(currentNodeName); + putCharInBuffer('>'); + } + + lastNodeOpen=FALSE; + return; + } + else if (nextChar == '>') + { + //the tag is just closed (maybe some content) + putNextCharsInBuffer(1); + subElementsProcessed = processElements(TRUE); + } + else + { + printError("processNode : Invalid character '%c'", nextChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + + //if the code reaches this area, then the processElements has been called and we must + //close the opening tag + char closeChar = getNextChar(); + if (closeChar != '<') + { + printError("processNode : Invalid character '%c' for closing tag (should be '<')", closeChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + + do + { + closeChar = readNextChar(); + putCharInBuffer(closeChar); + } + while(closeChar != '>'); + + //there is no elements + if (subElementsProcessed == 0) + { + //the node will be stripped + if (options->emptyNodeStripping) + { + //because we have '<nodeName ...></nodeName>' + xmlPrettyPrintedIndex -= nodeNameLength+4; + resetBackwardIndentation(TRUE); + + if (options->emptyNodeStrippingSpace) { putCharInBuffer(' '); } + putCharsInBuffer("/>"); + } + //the closing tag will be put on the same line + else if (options->inlineText) + { + //correct the index because we have '</nodeName>' + xmlPrettyPrintedIndex -= nodeNameLength+3; + resetBackwardIndentation(TRUE); + + //rewrite the node name + putCharsInBuffer("</"); + putCharsInBuffer(currentNodeName); + putCharInBuffer('>'); + } + } + + //the node is closed + lastNodeOpen = FALSE; + + //freeeeeeee !!! + free(nodeName); + nodeName = NULL; + currentNodeName = NULL; }
void processComment() { - gboolean inlineAllowed = FALSE; - if (options->inlineComment) { inlineAllowed = isInlineNodeAllowed(); } - if (inlineAllowed) { resetBackwardIndentation(TRUE); } - - putNextCharsInBuffer(4); //add the chars '<!--' - - char oldChar = '-'; - gboolean loop = TRUE; - while (loop) - { - char nextChar = readNextChar(); - if (oldChar == '-' && nextChar == '-') //comment is being closed - { - loop = FALSE; - } - - if (!isLineBreak(nextChar)) //the comment simply continues - { - putCharInBuffer(nextChar); - oldChar = nextChar; - } - else if (!options->oneLineComment) //oh ! there is a line break - { - readWhites(); //strip the whites and new line - putNewLine(); //put a new indentation line - oldChar = ' '; //and update the last char - - //TODO manage relative spacing - } - else //the comments must be inlined - { - readWhites(); //strip the whites and add a space if needed - if (getPreviousInsertedChar() != ' ') - { - putCharInBuffer(' '); - } - } - } - - char lastChar = readNextChar(); //should be '>' - if (lastChar != '>') - { - printError("processComment : last char must be '>' (not '%c')", lastChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - putCharInBuffer(lastChar); - - if (inlineAllowed) { appendIndentation = FALSE; } - - //there vas no node open - lastNodeOpen = FALSE; + gboolean inlineAllowed = FALSE; + if (options->inlineComment) { inlineAllowed = isInlineNodeAllowed(); } + if (inlineAllowed) { resetBackwardIndentation(TRUE); } + + putNextCharsInBuffer(4); //add the chars '<!--' + + char oldChar = '-'; + gboolean loop = TRUE; + while (loop) + { + char nextChar = readNextChar(); + if (oldChar == '-' && nextChar == '-') //comment is being closed + { + loop = FALSE; + } + + if (!isLineBreak(nextChar)) //the comment simply continues + { + putCharInBuffer(nextChar); + oldChar = nextChar; + } + else if (!options->oneLineComment) //oh ! there is a line break + { + readWhites(); //strip the whites and new line + putNewLine(); //put a new indentation line + oldChar = ' '; //and update the last char + + //TODO manage relative spacing + } + else //the comments must be inlined + { + readWhites(); //strip the whites and add a space if needed + if (getPreviousInsertedChar() != ' ') + { + putCharInBuffer(' '); + } + } + } + + char lastChar = readNextChar(); //should be '>' + if (lastChar != '>') + { + printError("processComment : last char must be '>' (not '%c')", lastChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + putCharInBuffer(lastChar); + + if (inlineAllowed) { appendIndentation = FALSE; } + + //there vas no node open + lastNodeOpen = FALSE; }
void processTextNode() { - //checks if inline is allowed - gboolean inlineTextAllowed = FALSE; - if (options->inlineText) { inlineTextAllowed = isInlineNodeAllowed(); } - if (inlineTextAllowed) { resetBackwardIndentation(TRUE); } //remove previous indentation - - //the leading whites are automatically stripped. So we re-add it - if (!options->trimLeadingWhites) - { - int backwardIndex = inputBufferIndex-1; - while (inputBuffer[backwardIndex] == ' ' || - inputBuffer[backwardIndex] == '\t') - { - --backwardIndex; //backward rolling - } - - //now the input[backwardIndex] IS NOT a white. So we go to - //the next char... - ++backwardIndex; - - //and then re-add the whites - while (inputBuffer[backwardIndex] == ' ' || - inputBuffer[backwardIndex] == '\t') - { - putCharInBuffer(inputBuffer[backwardIndex]); - ++backwardIndex; - } - } - - //process the text into the node - while(getNextChar() != '<') - { - char nextChar = readNextChar(); - if (isLineBreak(nextChar)) - { - readWhites(); - if (options->oneLineText) - { - //as we can put text on one line, remove the line break - //and replace it by a space but only if the previous - //char wasn't a space - if (getPreviousInsertedChar() != ' ') - { - putCharInBuffer(' '); - } - } - else - { - //put a new line only if the closing tag is not reached - if (getNextChar() != '<') - { - putNewLine(); - } - } - } - else - { - putCharInBuffer(nextChar); - } - } - - //strip the trailing whites - if (options->trimTrailingWhites) - { - while(getPreviousInsertedChar() == ' ' || - getPreviousInsertedChar() == '\t') - { - --xmlPrettyPrintedIndex; - } - } - - //remove the indentation for the closing tag - if (inlineTextAllowed) { appendIndentation = FALSE; } - - //there vas no node open - lastNodeOpen = FALSE; + //checks if inline is allowed + gboolean inlineTextAllowed = FALSE; + if (options->inlineText) { inlineTextAllowed = isInlineNodeAllowed(); } + if (inlineTextAllowed) { resetBackwardIndentation(TRUE); } //remove previous indentation + + //the leading whites are automatically stripped. So we re-add it + if (!options->trimLeadingWhites) + { + int backwardIndex = inputBufferIndex-1; + while (inputBuffer[backwardIndex] == ' ' || + inputBuffer[backwardIndex] == '\t') + { + --backwardIndex; //backward rolling + } + + //now the input[backwardIndex] IS NOT a white. So we go to + //the next char... + ++backwardIndex; + + //and then re-add the whites + while (inputBuffer[backwardIndex] == ' ' || + inputBuffer[backwardIndex] == '\t') + { + putCharInBuffer(inputBuffer[backwardIndex]); + ++backwardIndex; + } + } + + //process the text into the node + while(getNextChar() != '<') + { + char nextChar = readNextChar(); + if (isLineBreak(nextChar)) + { + readWhites(); + if (options->oneLineText) + { + //as we can put text on one line, remove the line break + //and replace it by a space but only if the previous + //char wasn't a space + if (getPreviousInsertedChar() != ' ') + { + putCharInBuffer(' '); + } + } + else + { + //put a new line only if the closing tag is not reached + if (getNextChar() != '<') + { + putNewLine(); + } + } + } + else + { + putCharInBuffer(nextChar); + } + } + + //strip the trailing whites + if (options->trimTrailingWhites) + { + while(getPreviousInsertedChar() == ' ' || + getPreviousInsertedChar() == '\t') + { + --xmlPrettyPrintedIndex; + } + } + + //remove the indentation for the closing tag + if (inlineTextAllowed) { appendIndentation = FALSE; } + + //there vas no node open + lastNodeOpen = FALSE; }
void processCDATA() { - gboolean inlineAllowed = FALSE; - if (options->inlineCdata) { inlineAllowed = isInlineNodeAllowed(); } - if (inlineAllowed) { resetBackwardIndentation(TRUE); } - - putNextCharsInBuffer(9); //putting the '<![CDATA[' into the buffer - - gboolean loop = TRUE; - char oldChar = '['; - while(loop) - { - char nextChar = readNextChar(); - char nextChar2 = getNextChar(); - if (oldChar == ']' && nextChar == ']' && nextChar2 == '>') { loop = FALSE; } //end of cdata - - if (!isLineBreak(nextChar)) //the cdata simply continues - { - putCharInBuffer(nextChar); - oldChar = nextChar; - } - else if (!options->oneLineCdata) - { - readWhites(); //strip the whites and new line - putNewLine(); //put a new indentation line - oldChar = ' '; //and update the last char - - //TODO manage relative spacing - } - else //cdata are inlined - { - readWhites(); //strip the whites and add a space if necessary - if(getPreviousInsertedChar() != ' ') { putCharInBuffer(' '); } - } - } - - char lastChar = readNextChar(); //should be '>' - if (lastChar != '>') - { - printError("processCDATA : last char must be '>' (not '%c')", lastChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - - putCharInBuffer(lastChar); - - if (inlineAllowed) { appendIndentation = FALSE; } - - //there vas no node open - lastNodeOpen = FALSE; + gboolean inlineAllowed = FALSE; + if (options->inlineCdata) { inlineAllowed = isInlineNodeAllowed(); } + if (inlineAllowed) { resetBackwardIndentation(TRUE); } + + putNextCharsInBuffer(9); //putting the '<![CDATA[' into the buffer + + gboolean loop = TRUE; + char oldChar = '['; + while(loop) + { + char nextChar = readNextChar(); + char nextChar2 = getNextChar(); + if (oldChar == ']' && nextChar == ']' && nextChar2 == '>') { loop = FALSE; } //end of cdata + + if (!isLineBreak(nextChar)) //the cdata simply continues + { + putCharInBuffer(nextChar); + oldChar = nextChar; + } + else if (!options->oneLineCdata) + { + readWhites(); //strip the whites and new line + putNewLine(); //put a new indentation line + oldChar = ' '; //and update the last char + + //TODO manage relative spacing + } + else //cdata are inlined + { + readWhites(); //strip the whites and add a space if necessary + if(getPreviousInsertedChar() != ' ') { putCharInBuffer(' '); } + } + } + + char lastChar = readNextChar(); //should be '>' + if (lastChar != '>') + { + printError("processCDATA : last char must be '>' (not '%c')", lastChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + + putCharInBuffer(lastChar); + + if (inlineAllowed) { appendIndentation = FALSE; } + + //there vas no node open + lastNodeOpen = FALSE; }
-void processDoctype() +void processDoctype() { - putNextCharsInBuffer(9); //put the '<!DOCTYPE' into the buffer - - gboolean loop = TRUE; - while(loop) - { - readWhites(); - putCharInBuffer(' '); //only one space for the attributes - - int nextChar = readNextChar(); - while(!isWhite(nextChar) && - !isQuote(nextChar) && //begins a quoted text - nextChar != '=' && //begins an attribute - nextChar != '>' && //end of doctype - nextChar != '[') //inner <!ELEMENT> types - { - putCharInBuffer(nextChar); - nextChar = readNextChar(); - } - - if (isWhite(nextChar)) {} //do nothing, just let the next loop do the job - else if (isQuote(nextChar) || nextChar == '=') - { - if (nextChar == '=') - { - putCharInBuffer(nextChar); - nextChar = readNextChar(); //now we should have a quote - - if (!isQuote(nextChar)) - { - printError("processDoctype : the next char should be a quote (not '%c')", nextChar); - result = PRETTY_PRINTING_INVALID_CHAR_ERROR; - return; - } - } - - //simply process the content - char quote = nextChar; - do - { - putCharInBuffer(nextChar); - nextChar = readNextChar(); - } - while (nextChar != quote); - putCharInBuffer(nextChar); //now the last char is the last quote - } - else if (nextChar == '>') //end of doctype - { - putCharInBuffer(nextChar); - loop = FALSE; - } - else //the char is a '[' => not supported yet - { - printError("DOCTYPE inner ELEMENT is currently not supported by PrettyPrinter\n"); - result = PRETTY_PRINTING_NOT_SUPPORTED_YET; - loop = FALSE; - } - } + putNextCharsInBuffer(9); //put the '<!DOCTYPE' into the buffer + + gboolean loop = TRUE; + while(loop) + { + readWhites(); + putCharInBuffer(' '); //only one space for the attributes + + int nextChar = readNextChar(); + while(!isWhite(nextChar) && + !isQuote(nextChar) && //begins a quoted text + nextChar != '=' && //begins an attribute + nextChar != '>' && //end of doctype + nextChar != '[') //inner <!ELEMENT> types + { + putCharInBuffer(nextChar); + nextChar = readNextChar(); + } + + if (isWhite(nextChar)) {} //do nothing, just let the next loop do the job + else if (isQuote(nextChar) || nextChar == '=') + { + if (nextChar == '=') + { + putCharInBuffer(nextChar); + nextChar = readNextChar(); //now we should have a quote + + if (!isQuote(nextChar)) + { + printError("processDoctype : the next char should be a quote (not '%c')", nextChar); + result = PRETTY_PRINTING_INVALID_CHAR_ERROR; + return; + } + } + + //simply process the content + char quote = nextChar; + do + { + putCharInBuffer(nextChar); + nextChar = readNextChar(); + } + while (nextChar != quote); + putCharInBuffer(nextChar); //now the last char is the last quote + } + else if (nextChar == '>') //end of doctype + { + putCharInBuffer(nextChar); + loop = FALSE; + } + else //the char is a '[' => not supported yet + { + printError("DOCTYPE inner ELEMENT is currently not supported by PrettyPrinter\n"); + result = PRETTY_PRINTING_NOT_SUPPORTED_YET; + loop = FALSE; + } + } }
void processDoctypeElement() { - printError("ELEMENT is currently not supported by PrettyPrinter\n"); - result = PRETTY_PRINTING_NOT_SUPPORTED_YET; + printError("ELEMENT is currently not supported by PrettyPrinter\n"); + result = PRETTY_PRINTING_NOT_SUPPORTED_YET; }
void printError(char *msg, ...) { - va_list va; - va_start(va, msg); - g_warning(msg, va); - va_end(va); - - //TODO also do a fprintf on stderr ? - - printDebugStatus(); + va_list va; + va_start(va, msg); + g_warning(msg, va); + va_end(va); + + //TODO also do a fprintf on stderr ? + + printDebugStatus(); }
void printDebugStatus() { - g_debug("\n===== INPUT =====\n%s\n=================\ninputLength = %d\ninputIndex = %d\noutputLength = %d\noutputIndex = %d\n", - inputBuffer, - inputBufferLength, - inputBufferIndex, - xmlPrettyPrintedLength, - xmlPrettyPrintedIndex); + g_debug("\n===== INPUT =====\n%s\n=================\ninputLength = %d\ninputIndex = %d\noutputLength = %d\noutputIndex = %d\n", + inputBuffer, + inputBufferLength, + inputBufferIndex, + xmlPrettyPrintedLength, + xmlPrettyPrintedIndex); }
Modified: trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h =================================================================== --- trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h 2010-04-18 09:45:35 UTC (rev 1253) +++ trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h 2010-04-19 14:06:13 UTC (rev 1254) @@ -43,25 +43,26 @@ */ typedef struct { - char* newLineChars; //char used to generate a new line (generally \r\n) - char indentChar; //char used for indentation - int indentLength; //number of char to use for indentation (by default 2 spaces) - gboolean oneLineText; //text is put on one line - gboolean inlineText; //if possible text are inline (no return after the opening node and before closing node) - gboolean oneLineComment; //comments are put on one line - gboolean inlineComment; //if possible comments are inline (no return after the opening node and before closing node) - gboolean oneLineCdata; //cdata are put on one line - gboolean inlineCdata; //if possible cdata are inline (no return after the opening node and before closing node) - gboolean emptyNodeStripping; //the empty nodes such <node></node> are set to <node/> - gboolean emptyNodeStrippingSpace; //put a space before the '/>' when a node is stripped - gboolean forceEmptyNodeSplit; //force an empty node to be splitted : <node /> becomes <node></node> (only if emptyNodeStripping = false) - gboolean trimLeadingWhites; //trim the leading whites in a text node - gboolean trimTrailingWhites; //trim the trailing whites in a text node -} PrettyPrintingOptions; + char* newLineChars; //char used to generate a new line (generally \r\n) + char indentChar; //char used for indentation + int indentLength; //number of char to use for indentation (by default 2 spaces) + gboolean oneLineText; //text is put on one line + gboolean inlineText; //if possible text are inline (no return after the opening node and before closing node) + gboolean oneLineComment; //comments are put on one line + gboolean inlineComment; //if possible comments are inline (no return after the opening node and before closing node) + gboolean oneLineCdata; //cdata are put on one line + gboolean inlineCdata; //if possible cdata are inline (no return after the opening node and before closing node) + gboolean emptyNodeStripping; //the empty nodes such <node></node> are set to <node/> + gboolean emptyNodeStrippingSpace; //put a space before the '/>' when a node is stripped + gboolean forceEmptyNodeSplit; //force an empty node to be splitted : <node /> becomes <node></node> (only if emptyNodeStripping = false) + gboolean trimLeadingWhites; //trim the leading whites in a text node + gboolean trimTrailingWhites; //trim the trailing whites in a text node +} +PrettyPrintingOptions;
//========================================== FUNCTIONS =========================================================
-int processXMLPrettyPrinting(char** xml, int* length, PrettyPrintingOptions* ppOptions); //process the pretty-printing on a valid xml string (no check done !!!). The ppOptions ARE NOT FREE-ED after processing. The method returns 0 if the pretty-printing has been done. -PrettyPrintingOptions* createDefaultPrettyPrintingOptions(); //creates a default PrettyPrintingOptions object +int processXMLPrettyPrinting(char** xml, int* length, PrettyPrintingOptions* ppOptions); //process the pretty-printing on a valid xml string (no check done !!!). The ppOptions ARE NOT FREE-ED after processing. The method returns 0 if the pretty-printing has been done. +PrettyPrintingOptions* createDefaultPrettyPrintingOptions(); //creates a default PrettyPrintingOptions object
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.