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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utilities for working with wayland protocols.
A collection of all the generically useful wayland utilities.
"""
from __future__ import absolute_import
from __future__ import print_function
import argparse
from xml.etree import ElementTree
def ReadProtocols(protocol_paths):
return [ElementTree.parse(path).getroot() for path in protocol_paths]
def AllInterfaces(protocols):
"""Get the interfaces in these protocols.
Args:
protocols: the list of protocols you want the interfaces of.
Yields:
Tuples (p, i) of (p)rotocol (i)nterface.
"""
for p in protocols:
for i in p.findall('interface'):
yield (p, i)
def AllMessages(protocols):
"""Get the messages in these protocols.
Args:
protocols: the list of protocols you want the messages of.
Yields:
Tuples (p, i, m) of (p)rotocol, (i)nterface, and (m)essage.
"""
for (p, i) in AllInterfaces(protocols):
for r in i.findall('request'):
yield (p, i, r)
for e in i.findall('event'):
yield (p, i, e)
def GetConstructorArg(message):
"""Get the argument that this message constructs, or None.
Args:
message: the message which you want to find the constructor arg of.
Returns:
The argument (as an ElementTree node) that constructs a new interface, or
None.
"""
return message.find('arg[@type="new_id"]')
def IsConstructor(message):
"""Check if a message is a constructor.
Args:
message: the message which you want to check.
Returns:
True if the message constructs an object (via new_id), False otherwise.
"""
return GetConstructorArg(message) is not None
def IsDestructor(message):
"""Check if a message is a destructor.
Args:
message: the message which you want to check.
Returns:
True if the message has the type='destructor' attribute, false otherwise.
"""
return message.get('type') == 'destructor'
def GetConstructedInterface(message):
"""Gets the interface constructed by a message.
Note that even if IsConstructor(message) returns true, get_constructed can
still return None when the message constructs an unknown interface (e.g.
wl_registry.bind()).
Args:
message: the event/request which may be a constructor.
Returns:
The name of the constructed interface (if there is one), or None.
"""
cons_arg = GetConstructorArg(message)
if cons_arg is None:
return None
return cons_arg.get('interface')
def NeedsListener(interface):
return interface.find('event') is not None
def GetDocumentation(element):
"""Return this element's documentation as a list of strings.
Args:
element: the xml.etree.ElementTree node you want the documentation for.
Returns:
A list of strings, containing the data from this node's "summary" attribute,
or its "description" subelement.
"""
doc = element.find('description')
if doc is None:
summary = element.get('summary')
return [summary] if summary is not None else []
ret = [doc.get('summary')]
if doc.text:
ret += [l.strip() for l in doc.text.split('\n')]
# Remove blank lines from the tail only.
while not ret[-1]:
ret.pop()
return ret
def ParseOpts(argv):
"""Parses the given command line arguments for the templater.
Args:
argv: the arguments to be parsed.
Returns:
An argparse.ArgumentParser which provides the user's chosen configuration
for this templater run.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
'-d',
'--directory',
help='treat input paths as relative to this directory',
default='.')
parser.add_argument(
'-i',
'--input',
help='path to the input template file (relative to -d)',
required=True)
parser.add_argument(
'-o',
'--output',
help='path to write the generated file to',
required=True)
parser.add_argument(
'-s',
'--spec',
help='path(s) to the wayland specification(s)',
nargs='+',
required=True)
return parser.parse_args(argv[1:])
|