aboutsummaryrefslogtreecommitdiffstats
path: root/timeseries
blob: 7a20c4c28c05056a16085c6a701fd61db5757792 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/perl
#
# Extract information on the fetchmail project size from the NEWS file
#
# Note: this only works if you have a news file from 5.1.1 or later --
# I didn't patch the code sizes into NEWS until then.
#
my($release, $date, $jdate);

%month_offsets = (
	"Jan",   0,
	"Feb",   31,
	"Mar",   59,
	"Apr",   90,
	"May",   120,
	"Jun",   151,
	"Jul",   181,
	"Aug",   212,
	"Sep",   243,
	"Oct",   273,
	"Nov",   304,
	"Dec",   334,
);


sub day_offset
{
    my($datestring) = @_;
    my($wday, $month, $day, $time, $zone, $year) = split(' ', $datestring);
    my($jdate);

    # We don't deal with leap years here because the baseline day is after
    # the last leap year (1996) and there's a long time before the next
    # one (2004).
    $jdate = ($year - 1996) * 365;

    $jdate += $month_offsets{$month};

    $jdate += ($day - 1);

    # Baseline day for the size data was Fri Oct 25 23:02:26 EDT 1996 
    $jdate -= 297;

    return($jdate);
}

open(NEWS, "NEWS");
$timestamp = `date`;
chop $timestamp;
$release = "unknown";
$lines = "unknown";
$date = "unknown";
$jdate = "unknown";
print <<EOF;
# Population data from fetchmail NEWS file, as of $timestamp.
#
# Output other than pass-through % lines is tab-separated fields.
# Field 1: release ID
# Field 2: count of source lines under version control 
# Field 3: count of fetchmail-friends subscribers
# Field 4: count of fetchmail-announce subscribers
# Field 5: total subscribers to both lists
# Field 6: date of release (days since first datum)
# Field 7: date of release (RFC822 date format)
#
EOF
while ($_ = <NEWS>)
{
    my($sum);

    if (/^%/) {
	print $_;
    }
    elsif (/^fetchmail-([^ ]*) \(([^)]+)\)(, [0-9]* lines)?:/) {
	$release = $1;
	$date = $2;
	$jdate = &day_offset($date);
	if ($3) {
	    $lines = substr($3, 2, length($3) - 8);
	} else {
	    $lines = 'na'
	}
    }
    elsif (/There are ([0-9]*) people on fetchmail-friends and ([0-9]*) on fetchmail-announce/) {
	$sum = $1 + $2;
	print "${release}\t${lines}\t$1\t$2\t${sum}\t${jdate}\t${date}\n";
	$release = "unknown";
	$date = "unknown";
    }
    elsif (/There are ([0-9]*) people on the fetchmail-friends list./) {
	print "$release\t${lines}\t$1\t0\t$1\t$jdate\t$date\n";
	$release = "unknown";
	$date = "unknown";
    }
}

# end
an> (l/60 + 1); out = v = xmalloc(l); t = stpcpy(out, "=?"); t = stpcpy(t, charset); t = stpcpy(t, "?Q?"); for (i = 0; i < nwords; i++) { const char *u; for (u = words[i]; *u; u++) { if (t - v >= 69) { t = stpcpy(t, "?=\r\n=?"); v = t - 2; t = stpcpy(t, charset); t = stpcpy(t, "?Q?"); } if (*u == ' ') { *t++ = '_'; continue; } if (strchr(encchars, *u)) { *t++ = *u; continue; } sprintf(t, "=%02X", (unsigned int)((unsigned char)*u)); t += 3; } } strcpy(t, "?="); return out; } /** RFC-2047 encode string with given charset. Only the Q encoding * (quoted-printable) supported at this time. * WARNING: this code returns a static buffer! */ char *rfc2047e(const char *string, const char *charset) { static char *out; char *t; const char *r; int count, minlen, idx, i; char **words = NULL; size_t l; assert(strlen(charset) < 40); if (out) { free(out); out = NULL; } /* phase 1: split original into words */ /* 1a: count, 1b: copy */ count = 0; r = string; while (*r) { count++; r += strcspn(r, ws); if (!*r) break; count++; r += strspn(r, ws); } words = (char **)xmalloc(sizeof(char *) * (count + 1)); idx = 0; r = string; while (*r) { l = strcspn(r, ws); words[idx] = xmalloc(l+1); memcpy(words[idx], r, l); words[idx][l] = '\0'; idx++; r += l; if (!*r) break; l = strspn(r, ws); words[idx] = xmalloc(l+1); memcpy(words[idx], r, l); words[idx][l] = '\0'; idx++; r += l; } /* phase 2: encode words */ /* a: find ranges of adjacent words to need encoding */ /* b: encode ranges */ idx = 0; while (idx < count) { int end; char *tmp; if (!needs_enc(words[idx])) { idx += 2; continue; } for (end = idx + 2; end < count; end += 2) { if (!needs_enc(words[end])) break; } end -= 2; tmp = encode_words(&words[idx], end - idx + 1, charset); free(words[idx]); words[idx] = tmp; for (i = idx + 1; i <= end; i++) words[i][0] = '\0'; idx = end + 2; } l = 0; for (idx = 0; idx < count; idx++) { l += strlen(words[idx]); } /* phase 3: limit lengths */ minlen = strlen(charset) + 7; /* allocate ample memory */ out = xmalloc(l + (l / (72 - minlen) + 1) * (minlen + 2) + 1); if (count) t = stpcpy(out, words[0]); else t = out, *out = 0; l = strlen(out); for (i = 1; i < count; i+=2) { size_t m; char *tmp; m = strlen(words[i]); if (i + 1 < count) m += strcspn(words[i+1], "\r\n"); if (l + m > 74) l = 0, t = stpcpy(t, "\r\n"); t = stpcpy(t, words[i]); if (i + 1 < count) { t = stpcpy(t, words[i+1]); } tmp = strrchr(out, '\n'); if (tmp == NULL) tmp = out; else tmp++; l = strlen(tmp); } /* free memory */ for (i = 0; i < count; i++) free(words[i]); free(words); return out; } #ifdef TEST int main(int argc, char **argv) { char *t; if (argc > 1) { t = rfc2047e(argv[1], argc > 2 ? argv[2] : "utf-8"); printf( " input: \"%s\"\n" "output: \"%s\"\n", argv[1], t); free(t); } return EXIT_SUCCESS; } #endif