GSList * log_read_dates (gchar **buffer_lines, time_t current) { int offsetyear = 0, current_year; GSList *days = NULL, *days_copy; GDate *date, *newdate; struct tm *tmptm; gchar *date_string; Day *day; gboolean done = FALSE; int i, n, rangemin, rangemax; if (buffer_lines == NULL) return NULL; n = g_strv_length (buffer_lines); for (i=0; buffer_lines[i]==NULL; i++); tmptm = localtime (¤t); current_year = tmptm->tm_year + 1900; for (i=0; buffer_lines[i]==NULL; i++); /* Start building the list */ /* Scanning each line to see if the date changed is too slow, so we proceed in a recursive fashion */ date = string_get_date (buffer_lines[i]); if ((date==NULL)|| !g_date_valid (date)) return NULL; g_date_set_year (date, current_year); day = g_new (Day, 1); days = g_slist_append (days, day); day->date = date; day->first_line = i; day->last_line = -1; date_string = string_get_date_string (buffer_lines[i]); rangemin = 0; rangemax = n-1; while (!done) { i = n-1; while (day->last_line < 0) { if (g_str_has_prefix (buffer_lines[i], date_string)) { if (i == (n-1)) { day->last_line = i; done = TRUE; break; } else { if (!g_str_has_prefix (buffer_lines[i+1], date_string)) { day->last_line = i; break; } else { rangemin = i; i = floor ( ((float) i + (float) rangemax)/2.); } } } else { rangemax = i; i = floor (((float) rangemin + (float) i)/2.); } } g_free (date_string); if (!done) { /* We need to find the first line now that has a date Logs can have some messages without dates ... */ newdate = NULL; while (newdate == NULL && !done) { i++; date_string = string_get_date_string (buffer_lines[i]); if (date_string == NULL) continue; newdate = string_get_date (buffer_lines[i]); if (newdate == NULL && i==n-1) done = TRUE; } day->last_line = i-1; /* Append a day to the list */ if (newdate) { g_date_set_year (newdate, current_year + offsetyear); if (g_date_compare (newdate, date) < 1) { offsetyear++; /* newdate is next year */ g_date_add_years (newdate, 1); } date = newdate; day = g_new (Day, 1); days = g_slist_append (days, day); day->date = date; day->first_line = i; day->last_line = -1; rangemin = i; rangemax = n; } } } /* Correct years now. We assume that the last date on the log is the date last accessed */ for (days_copy = days; days_copy != NULL; days_copy = g_slist_next (days_copy)) { day = days_copy -> data; g_date_subtract_years (day->date, offsetyear); } /* Sort the days in chronological order */ days = g_slist_sort (days, days_compare); return (days); }