diff --git a/lineoperations/README b/lineoperations/README index 2728b3b7a..79c7fd4f6 100644 --- a/lineoperations/README +++ b/lineoperations/README @@ -16,6 +16,7 @@ Features * Remove Duplicate Lines, sorted * Remove Duplicate Lines, ordered * Remove Unique Lines +* Keep Unique Lines * Remove Empty Lines * Remove Whitespace Lines * Sort Lines Ascending @@ -113,6 +114,32 @@ Removes all lines that appear only once. Line 1 Line 2 + +Keep Unique Lines +------------------- + +Keep all lines that appear only once. + + Example: Suppose a file has the following lines. (#comments added for + clarity) + + :: + + Line 4 + Line 1 #removed + Line 2 #removed + Line 3 + Line 1 #removed + Line 2 #removed + + The **Keep Unique Lines** will change the file into this: + + :: + + Line 4 + Line 3 + + Remove Empty Lines ------------------ diff --git a/lineoperations/src/linefunctions.c b/lineoperations/src/linefunctions.c index 32938d83f..edd662a1c 100644 --- a/lineoperations/src/linefunctions.c +++ b/lineoperations/src/linefunctions.c @@ -159,6 +159,50 @@ rmunqln(gchar **lines, gint num_lines, gchar *new_file) } +/* Keep Unique Lines */ +gint +kpunqln(gchar **lines, gint num_lines, gchar *new_file) +{ + gchar *nf_end = new_file; /* points to last char of new_file */ + gint i = 0; /* iterator */ + gint j = 0; /* iterator */ + gboolean *to_remove = NULL; /* to 'mark' which lines to remove */ + gint changed = 0; /* number of lines removed */ + + + /* allocate and set *to_remove to all FALSE + * to_remove[i] represents whether lines[i] should be removed */ + to_remove = g_malloc(sizeof(gboolean) * num_lines); + for(i = 0; i < num_lines; i++) + to_remove[i] = FALSE; + + /* find all non unique lines and set them to TRUE (to be removed) */ + for(i = 0; i < num_lines; i++) + /* make sure that the line is not already determined to be non unique */ + if(!to_remove[i]) + for(j = (i+1); j < num_lines; j++) + if(!to_remove[j] && strcmp(lines[i], lines[j]) == 0) + { + to_remove[i] = TRUE; + to_remove[j] = TRUE; + } + + /* copy **lines into 'new_file' if it is not FALSE(not duplicate) */ + for(i = 0; i < num_lines; i++) + if(!to_remove[i]) + { + changed++; /* number of lines kept */ + nf_end = g_stpcpy(nf_end, lines[i]); + } + + /* free used memory */ + g_free(to_remove); + + /* return the number of lines deleted */ + return -(num_lines - changed); +} + + /* Remove Empty Lines */ gint rmemtyln(ScintillaObject *sci, gint line_num, gint end_line_num) diff --git a/lineoperations/src/linefunctions.h b/lineoperations/src/linefunctions.h index 9b91dabd1..5829c43c4 100644 --- a/lineoperations/src/linefunctions.h +++ b/lineoperations/src/linefunctions.h @@ -45,6 +45,11 @@ gint rmunqln(gchar **lines, gint num_lines, gchar *new_file); +/* Keep Unique Lines */ +gint +kpunqln(gchar **lines, gint num_lines, gchar *new_file); + + /* Remove Empty Lines */ gint rmemtyln(ScintillaObject *sci, gint line_num, gint end_line_num); diff --git a/lineoperations/src/lineoperations.c b/lineoperations/src/lineoperations.c index 370a4640e..6e3ddb364 100644 --- a/lineoperations/src/lineoperations.c +++ b/lineoperations/src/lineoperations.c @@ -257,6 +257,8 @@ lo_init(GeanyPlugin *plugin, gpointer gdata) G_CALLBACK(action_indir_manip_item), (gpointer) rmdupln }, { N_("Remove _Unique Lines"), G_CALLBACK(action_indir_manip_item), (gpointer) rmunqln }, + { N_("Keep _Unique Lines"), + G_CALLBACK(action_indir_manip_item), (gpointer) kpunqln }, { NULL }, { N_("Remove _Empty Lines"), G_CALLBACK(action_sci_manip_item), (gpointer) rmemtyln },