Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XF86XK_AudioForward is not exported #21

Open
nagisa opened this issue Jul 27, 2013 · 6 comments
Open

XF86XK_AudioForward is not exported #21

nagisa opened this issue Jul 27, 2013 · 6 comments

Comments

@nagisa
Copy link

nagisa commented Jul 27, 2013

XF86XK_AudioForward is not exported from Graphics.X11.ExtraTypes.XF86 even though a similar XF86XK_AudioRewind is.

@dmwit
Copy link
Contributor

dmwit commented Jul 27, 2013

Okay. There's actually a lot of symbols missing. It's a generated file, and the script that generated it seems not to be in revision control. I've emailed the guy who added XF86.hsc to the repository to see if he still has the script lying around. If not, or I don't hear from him, I'll take a stab at writing a new script.

@dmwit
Copy link
Contributor

dmwit commented Dec 6, 2013

Just got an email from zythmer. The relevant files, which he placed in the public domain, follow.

HsAllKeySyms.h:

#ifndef HSALLKEYSYMS_H
#define HSALLKEYSYMS_H 1

/* Defaults */
#include <X11/keysym.h>

/* Vendor specific */
#include <X11/DECkeysym.h>
#include <X11/Sunkeysym.h>
#include <X11/ap_keysym.h>
#include <X11/HPkeysym.h>
#include <X11/XF86keysym.h>

#endif /* HSALLKEYSYMS_H */

gen.sh:

#!/bin/sh

echo "Regenerating all of the keysym files..."

rm -f *.hsc

perl create_hsc_keysym.pl XorgDefault  /usr/include/X11/keysymdef.h    > XorgDefault.hsc
perl create_hsc_keysym.pl DEC  /usr/include/X11/DECkeysym.h  > DEC.hsc
perl create_hsc_keysym.pl HP   /usr/include/X11/HPkeysym.h   > HP.hsc
perl create_hsc_keysym.pl Sun  /usr/include/X11/Sunkeysym.h  > Sun.hsc
perl create_hsc_keysym.pl XF86 /usr/include/X11/XF86keysym.h > XF86.hsc
perl create_hsc_keysym.pl AP   /usr/include/X11/ap_keysym.h  > AP.hsc

for file in $(ls *.hsc); do
    echo "Running hsc2hs on $file"
    hsc2hs $file
done

check.sh:

    #!/bin/sh

# Generate the hs files and check that it appears the number of entries
# are the same.

echo "Finding the count for X11 includes..."
for file in $(ls /usr/include/X11/*keysym* | grep -v "/keysym\.h$" | sort); do
    count=$(grep "^ *#define.*XK_" $file  | wc -l);
    haskell_count=$(echo "$count * 2" | bc);
    echo "$file has $count defines (hsc should have $haskell_count)";
done

# Generating Haskell files
sh gen.sh

echo "Finding the count from generated Haskell..."
for file in $(ls *.hsc | sort); do
    count=$(egrep -v "^ *(--|#)" $file | grep "[xX]K_" | wc -l);
    echo "$file has $count symbols";
done

create_hsc_keysym.pl, the real workhorse:

# NOTE: I have to manually remove VoidSymbol, MISCELLANY and LATIN1
# because Graphics.X11.Types already includes those.

use strict;
use warnings;
use Carp;
use Data::Dumper;

if ($#ARGV != 1) {
    confess qq{Must pass in a name and file for this module};
}

my $debug = 0;

my $name = $ARGV[0];
my $file = $ARGV[1];

print<<"EOF";
-- Generated from $file
--

EOF

my @entries = get_entries($file);
print_hsc($name, @entries);

# Haskell reserves names that start with a capital for classes/types.
sub get_haskell_name {
    my ($current) = @_;

    # It doesn't matter if the Haskell name and X name are the same
    # in the enum statements.
    return lcfirst($current);
}

sub print_hsc {
    my ($name, @entries) = @_;

    # Print the assumed copyright section.
    foreach my $entry (@entries) {
        if (ref($entry) ne 'HASH') {
            confess qq{Shouldn't be here: $!};
        }
        if (exists($entry->{copyright})) {
            print "-- " . $entry->{copyright} . "\n";
        }
    }

    print<<"EOF";

module XMonad.Contrib.Keysyms.$name
        (
EOF

    # Find the longest entry so we can properly print this.
    my $longest = 0;
    foreach my $entry (@entries) {
        if (exists($entry->{key})) {
            if (length($entry->{key}) > $longest) {
                $longest = length($entry->{key});
            }
        }
    }

    # +1 for comma and +2 for room.
    $longest += 3;

    # We need to print the module export list.
    foreach my $entry (@entries) {
        if (ref($entry) ne 'HASH') {
            confess qq{Shouldn't be here: $!};
        }

        if (exists($entry->{key}) && defined($entry->{comment})) {
            printf("%9s%-${longest}s -- %s\n", " ",
                   get_haskell_name($entry->{key}) . ",", $entry->{comment});

        } elsif (exists($entry->{key})) {
            printf("%9s%-${longest}s\n", " ",
                   get_haskell_name($entry->{key}) . ",");

        } elsif (exists($entry->{ifdef})) {
            print "#ifdef " . $entry->{ifdef} . "\n";
            print "\n         -- " . $entry->{ifdef} . "\n";

        } elsif (exists($entry->{endif})) {
            print "#else\n";
            print "         -- Skipped " . $entry->{endif} . " because your X does not support it\n";
            print "#endif\n";

        } elsif (exists($entry->{comment})) {
            print "\n         -- " . $entry->{comment} . "\n";

        }
    }

    print<<"EOF";
        ) where

import Graphics.X11.Types

#include "HsAllKeysyms.h"

#{enum KeySym,
EOF

    # Note: Do not print comments in the enum section.
    my $need_close = 0;
    foreach my $entry (@entries) {
        if (exists($entry->{key})) {
            printf(" , %-${longest}s = %s\n",
                   get_haskell_name($entry->{key}), $entry->{key});
            $need_close = 1;

        } elsif (exists($entry->{ifdef})) {
            print " }\n\n"   if ($need_close);
            print "#ifdef " . $entry->{ifdef} . "\n";
            print "#{enum KeySym,\n";

        } elsif (exists($entry->{endif})) {
            print " }\n";
            print "#else\n";
            print "-- Skipped " . $entry->{endif} . " because your X does not support it.\n";
            print "#endif\n\n";
            $need_close = 0;
        }
    }
    print " }\n\n"  if ($need_close);
}

sub get_entries {
    my ($file) = @_;

    open(my $fh, $file) || confess qq{Couldn't open: $!};

    my $state = 0;

    my @entries;
    my @ifdefs;
    my ($found_blank_line, $can_check) = (0,0);
    while (my $line = <$fh>) {
        chomp($line);

        # Check for the copyright.  It's assumed that the copyright is
        # a series of commented out lines.  A blank line after '*/' is
    # assumed to start the code.
        if (! $found_blank_line) {
            if ($line =~ m{^\s*
                           /\*{1,}(.*)
                           $}mix) {
                push(@entries, { copyright => $1 });
                $state = 1;
                print "-- start copyright\n"  if $debug;
                $can_check = 0;

            } elsif ($line =~ m{^\s*
                               (.*?)\*+/\s*
                               $}mix) {
                push(@entries, { copyright => $1 });
                print "-- end copyright\n"   if $debug;
                $can_check = 1;

            } elsif ($can_check && $line =~ m{^\s*$}) {
                $found_blank_line = 1;

            } else {
                $line =~ s{^\s+}{};
                push(@entries, { copyright => $line });
            }
        }

        print "-- \t$line\n"  if $debug;
        if ($line =~ m{^\s*
                       /\*+(.*)\*+/
                       \s*$}mix) {
            push(@entries, { comment =>  $1 });
            print "-- Found comment\n"  if $debug;

        } elsif ($line =~ m{^\s*
                       /\*{1,}.*
                       $}mix) {
            $state = 1;
            print "-- Found start_comment\n"  if $debug;

        } elsif ($state == 1
                 && $line =~ m{^\s*
                               .*\*/.*
                               $}mix) {
            $state = 0;
            print "-- end start_comment\n"   if $debug;

        } elsif ($state == 0) {
            if ($line =~ m{^\s*
                           \#define\s+
                           (\S*K_\S+)       # $1 = keysym
                           \s+
                           (0x[0-9A-Fa-f]+) # $2 = value
                           \s*
                           (?:
                             /\*(.+)\*/       # $3 = comment
                           )?
                           \s*
                         $}mix) {
                push(@entries,
                     { key => $1, value => $2, comment => $3 });
                print "-- define\n"   if $debug;

            } elsif ($line =~ m{^\s*
                                \#ifdef\s+
                                (\S*K_\S+)  # $1 = keysym type
                                \s*$}mix) {

                push(@entries, { ifdef => $1 });
                push(@ifdefs, $1);
                print "-- ifdef\n"   if $debug;

            } elsif (scalar(@ifdefs) > 0
                     && $line =~ m{^\s*
                                    \#endif
                                    .*$}mix) {
                push(@entries, { endif => pop(@ifdefs) });
                print "-- endif\n"  if $debug;
            }
        }
    }

    close($fh) || confess qq{Couldn't close: $!};

    return @entries;
}

@terjr
Copy link

terjr commented Mar 20, 2014

Shouldn't these files be put in the repository?
And by the way, there is a bug in {gen,check}.sh.

for file in $(ls *.hsc); do

is unsafe. It should be:

for file in *.hsc; do

@pjones
Copy link
Contributor

pjones commented Dec 14, 2016

How do we want to maintain the hsc file going forward? Accept patches or take ownership of these perl scripts and put them in the repo?

@sboosali
Copy link

Any update?

@dmwit
Copy link
Contributor

dmwit commented Apr 21, 2018

@sboosali I took a brief look today. These scripts appear to work, but the files they generate are waaaay too different from the files that are currently in the repository for my taste. As far as I can tell I would have to manually review each updated hsc file to check that nothing important has been lost; I'm not going to do that.

If somebody wants to update the scripts to make the diffs more manageable, I'll reconsider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants