Bill hasn't checked in with his reports yet.  The three failures in
i686-linux are all old, and due to the same problem in setting up the
GTK device tag for the font/face specifiers, now corrected.
Data is the monthly tarballs of xemacs-build-reports starting last
August.  There were no build reports in September.  The results are
basically the same if I just use the last few weeks, except that N is
about 40.  I will do this correctly later, but I think this version is
of some interest for the list of platforms and frequency of reporting
stats.
N is the total number of build reports from August to date.
GTK src is the number of reports based on src using GTK based on a
  crude heuristic.  (see the Python script below.)
gtk=no is the number of GTK source builds --with-gtk=no.
OK is the number of successes, based on parsing the build report
  Subject for "success".
rate = 100*OK/(gtk=no).
Platform                         N  GTK src   gtk=no       OK   rate
hppa1.1-hp-hpux11.00:            1        0        0        0     na
hppa2.0-hp-hpux11.00:            1        0        0        0     na
i386-debian-linux:               2        2        1        1   100%
i386-pc-win32:                   3        0        0        0     na
i386-unknown-freebsd3.3:         6        0        0        0     na
i386-unknown-freebsd3.4:         3        0        0        0     na
i386-unknown-freebsd4.1:         7        0        0        0     na
i386-unknown-freebsd5.0:        10        0        0        0     na
i386-unknown-openbsd2.7:         2        0        0        0     na
i386-unknown-openbsd2.8:         3        1        1        1   100%
i586-pc-linux:                  11        0        0        0     na
i586-pc-sco3.2v5.0.2:            2        0        0        0     na
i586-pc-win32:                   4        0        0        0     na
i686-pc-linux:                  45        6        5        2    40%
mips-sgi-irix6.2:                5        0        0        0     na
powerpc-unknown-linux:           9        0        0        0     na
sparc-sun-solaris2.5.1:          3        0        0        0     na
sparc-sun-solaris2.6:            1        0        0        0     na
sparc-sun-solaris2.7:           11        0        0        0     na
sparc-sun-solaris2.8:            4        3        2        2   100%
unknown:                         2        0        0        0     na
Totals (by hand)               135       12        9        6    67%
#! /usr/bin/python
# scaffolding = stuff that needs generalization
dir = 'build-reports/'
root = 'xemacs-build-reports.'
stem = dir + root
months = ['200008', '200010', '200011', '200012',
'200101', '200102']
##
## imports
##
import re
from string import strip, lower
##
## input functions
##
def parseFile (filename):
    """Parse an xemacs-build-reports archive file.
    Assumes that a database (actually list of records) is in `db'."""
    # slurp in file
    file = open(filename, 'r')
    lines = file.readlines()
    file.close()
    # process it
    for line in lines:
        # check for message start, initialize record
        if re.match('from ', line, re.I):
            inHeaders = 1
            currentProperty = None
            record = { 'gtk' : '' }
            if re.search('gtk', line, re.I):
                record['gtk'] += line
            db.append(record)
            # should try to parse out an address
            continue
        if re.search('gtk', line, re.I):
            record['gtk'] += line
        # parse header lines
        if inHeaders:
            if re.match('^$', line):
                inHeaders = 0
                continue
            m = re.match('([-_A-Za-z0-9]+)\s*:(.*)$', line)
            if m:
                currentHeader = lower(strip(m.group(1)))
                if not re.match(ignoredHeaderRE, currentHeader, re.I):
                    record[currentHeader] = strip(m.group(2))
                    # print line,
                else:
                    currentHeader = None
            elif currentHeader:
                if re.match('\s', line):
                    # print currentHeader
                    record[currentHeader] += ' ' + strip(line)
                else:
                    # something evil happened
                    record[currentHeader] += ' ' + strip(line)
            else:
                pass
        # parse body lines
        # assume each property is in a given section headed by a line matching
        # its keyword
        # sections terminated by empty lines
        elif not currentProperty:
            m = re.search('uname |configure |configured for ',line)
            if m:
                currentProperty = lower(strip(m.group(0)))
                if record.has_key(currentProperty):
                    record[currentProperty] += '\n' + strip(line)
                else:
                    record[currentProperty] = strip(line)
        elif re.match('uname|configure|configured for', currentProperty):
            if strip(line):
                record[currentProperty] += ' ' + strip(line)
            else:
                currentProperty = None
        else:
            print '***** currentProperty not handled: %s' % (currentProperty)
##
## functions to parse specific information from a record
##
def parseSubject (record):
    """Parse status from Subject header of RECORD.
    Adds status field to RECORD."""
    
    if record.has_key('subject'):
        m = re.search('success|failure',record['subject'],re.I)
        if m:
            record['status'] = lower(m.group(0))
        else:
            record['status'] = 'unknown'
def parseConfiguration (record):
    """Parse version, codename, and platform from configuration line of
RECORD.
    Adds version, codename, and platform fields to RECORD."""
    
    if record.has_key('configured for'):
        m = re.match('XEmacs (\\S*) \\\\?"(.*)\\\\?" configured for
`(.*)\'',
                     record['configured for'],re.I)
        if m:
            record['version'] = m.group(1)
            record['codename'] = m.group(2)
            record['platform'] = m.group(3)
        else:
            print 'Broken version: ' + record['configured for']
            record['codename'] = 'unknown'
            record['version'] = 'unknown'
            record['platform'] = 'unknown'
    else:
        record['codename'] = 'unknown'
        record['version'] = 'unknown'
        record['platform'] = 'unknown'
def parseConfigure (record):
    """Parse important switches out of the ./configure command line of
RECORD.
    Adds appropriate switch fields to RECORD."""
    
    if record.has_key('configure'):
        m =
re.search('--with(out)?-gtk(=yes|=no)?',record['configure'],re.I)
        if m:
            if m.group(1):
                if m.group(2):
                    record['with-gtk'] = 'confused'
                else:
                    record['with-gtk'] = 'no'
            else:
                if m.group(2):
                    record['with-gtk'] = lower(m.group(2)[1:])
                else:
                    record['with-gtk'] = 'yes'
        else:
            record['with-gtk'] = 'no'
    else: record['with-gtk'] = 'missing'
##
## reporting functions
##
def gtkByPlatform ():
    """Check on --with-gtk=no testing by platform."""
    gtkPlatforms = {}
    for record in db:
        if not gtkPlatforms.has_key(record['platform']):
            gtkPlatforms[record['platform']] = (0, 0, 0, 0)
        yes, no, withGTK, withoutGTK = gtkPlatforms[record['platform']]
        if record['gtk']: yes += 1
        else: no += 1
        if record['with-gtk'] == 'yes': withGTK += 1
        elif record['with-gtk'] == 'no': withoutGTK += 1
        gtkPlatforms[record['platform']] = (yes, no, withGTK, withoutGTK)
    print '%-30s %9s %9s %9s %9s' % ('Platform','GTK
src','mainline','gtk=yes','gtk=no')
    keys = gtkPlatforms.keys()
    keys.sort()
    for platform in keys:
        print '%-30s' % (platform + ':'),
        print '%9d %9d %9d %9d' % gtkPlatforms[platform]
def gtkIsNoSuccessRateByPlatform ():
    """Check on success rate of --with-gtk=no testing by
platform."""
    gtkPlatforms = {}
    for record in db:
        if not gtkPlatforms.has_key(record['platform']):
            gtkPlatforms[record['platform']] = (0, 0, 0, 0)
        n, GTKsrc, notGTK, ok = gtkPlatforms[record['platform']]
        n += 1
        if record['gtk']:
            GTKsrc += 1
            if record['with-gtk'] == 'no':
                notGTK += 1
                if record['status'] == 'success': ok += 1
        gtkPlatforms[record['platform']] = (n, GTKsrc, notGTK, ok)
    print '%-30s %3s %8s %8s %8s %6s' \
          % ('Platform','N','GTK
src','gtk=no','OK', 'rate')
    keys = gtkPlatforms.keys()
    keys.sort()
    for platform in keys:
        n, GTKsrc, notGTK, ok = gtkPlatforms[platform]
        print '%-30s' % (platform + ':'),
        print '%3d %8d %8d %8d' % (n, GTKsrc, notGTK, ok),
        if notGTK: print '%5s%%' % ((100*ok)/notGTK)
        else: print '%6s' % 'na'
##
## main program
##
ignoredHeaderRE = 'received|to|cc|sender|x-.*|mime-.*|content-*'
db = []
# create database
for month in months:
    parseFile(stem + month)
# process records
for record in db:
    parseSubject (record)
    parseConfiguration (record)
    parseConfigure (record)
#gtkByPlatform()
gtkIsNoSuccessRateByPlatform()
-- 
University of Tsukuba                Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
Institute of Policy and Planning Sciences       Tel/fax: +81 (298) 53-5091
_________________  _________________  _________________  _________________
What are those straight lines for?  "XEmacs rules."