def Process(self, rctext, rc_path):
        '''Processes 'rctext' and returns a resource tree corresponding to it.

    Args:
      rctext: complete text of the rc file
      rc_path: 'resource\resource.rc'

    Return:
      grit.node.base.Node subclass
    '''

        if self.pre_process:
            preprocess_class = util.NewClassInstance(
                self.pre_process, preprocess_interface.PreProcessor)
            if preprocess_class:
                rctext = preprocess_class.Process(rctext, rc_path)
            else:
                self.Out(
                    'PreProcessing class could not be found. Skipping preprocessing.\n'
                )

        # Start with a basic skeleton for the .grd file
        root = grd_reader.Parse(
            StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?>
      <grit base_dir="." latest_public_release="0"
          current_release="1" source_lang_id="en">
        <outputs />
        <translations />
        <release seq="1">
          <includes />
          <structures />
          <messages />
        </release>
      </grit>'''), util.dirname(rc_path))
        includes = root.children[2].children[0]
        structures = root.children[2].children[1]
        messages = root.children[2].children[2]
        assert (isinstance(includes, grit.node.empty.IncludesNode)
                and isinstance(structures, grit.node.empty.StructuresNode)
                and isinstance(messages, grit.node.empty.MessagesNode))

        self.AddIncludes(rctext, includes)
        self.AddStructures(rctext, structures, os.path.basename(rc_path))
        self.AddMessages(rctext, messages)

        self.VerboseOut('Validating that all IDs are unique...\n')
        root.ValidateUniqueIds()
        self.ExtraVerboseOut('Done validating that all IDs are unique.\n')

        if self.post_process:
            postprocess_class = util.NewClassInstance(
                self.post_process, postprocess_interface.PostProcessor)
            if postprocess_class:
                root = postprocess_class.Process(rctext, rc_path, root)
            else:
                self.Out(
                    'PostProcessing class could not be found. Skipping postprocessing.\n'
                )

        return root
Exemple #2
0
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.File
      outfile: open filehandle
    '''
    base_dir = util.dirname(output_node.GetOutputFilename())

    try:
      formatter = node.ItemFormatter(output_node.GetType())
      if formatter:
        outfile.write(formatter.Format(node, output_node.GetLanguage(),
                                       begin_item=True, output_dir=base_dir))
    except:
      print u"Error processing node %s" % unicode(node)
      raise

    for child in node.children:
      RcBuilder.ProcessNode(child, output_node, outfile)

    try:
      if formatter:
        outfile.write(formatter.Format(node, output_node.GetLanguage(),
                                       begin_item=False, output_dir=base_dir))
    except:
      print u"Error processing node %s" % unicode(node)
      raise
Exemple #3
0
    def ProcessNode(node, output_node, outfile):
        '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.OutputNode
      outfile: open filehandle
    '''
        base_dir = util.dirname(output_node.GetOutputFilename())

        formatter = GetFormatter(output_node.GetType())
        formatted = formatter(node,
                              output_node.GetLanguage(),
                              output_dir=base_dir)
        # NB: Formatters may be generators or return lists.  The writelines API
        # accepts iterables as a shortcut to calling write directly.  That means
        # you can pass strings (iteration yields characters), but not bytes (as
        # iteration yields integers).  Python 2 worked due to its quirks with
        # bytes/string implementation, but Python 3 fails.  It's also a bit more
        # inefficient to call write once per character/byte.  Handle all of this
        # ourselves by calling write directly on strings/bytes before falling back
        # to writelines.
        if isinstance(formatted, (six.string_types, six.binary_type)):
            outfile.write(formatted)
        else:
            outfile.writelines(formatted)
        if output_node.GetType() == 'data_package':
            with open(output_node.GetOutputFilename() + '.info',
                      'w') as infofile:
                if node.info:
                    # We terminate with a newline so that when these files are
                    # concatenated later we consistently terminate with a newline so
                    # consumers can account for terminating newlines.
                    infofile.writelines(['\n'.join(node.info), '\n'])
Exemple #4
0
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.
    
    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.File
      outfile: open filehandle
    '''
    base_dir = util.dirname(output_node.GetOutputFilename())
    
    try:
      formatter = node.ItemFormatter(output_node.GetType())
      if formatter:
        outfile.write(formatter.Format(node, output_node.GetLanguage(),
                                       begin_item=True, output_dir=base_dir))
    except:
      print u"Error processing node %s" % unicode(node)
      raise

    for child in node.children:
      RcBuilder.ProcessNode(child, output_node, outfile)

    try:
      if formatter:
        outfile.write(formatter.Format(node, output_node.GetLanguage(),
                                       begin_item=False, output_dir=base_dir))
    except:
      print u"Error processing node %s" % unicode(node)
      raise
Exemple #5
0
def Parse(filename_or_stream, dir=None, flexible_root=False,
          stop_after=None, debug=False, first_id_filename=None,
          defines=None):
  '''Parses a GRD file into a tree of nodes (from grit.node).

  If flexible_root is False, the root node must be a <grit> element.  Otherwise
  it can be any element.  The "own" directory of the file will only be fixed up
  if the root node is a <grit> element.

  'dir' should point to the directory of the input file, or be the full path
  to the input file (the filename will be stripped).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If first_id_filename is provided, then we use the provided path instead of
  resources_id to gather the first id values for resources.

  Args:
    filename_or_stream: './bla.xml'  (must be filename if dir is None)
    dir: '.' or None (only if filename_or_stream is a filename)
    flexible_root: True | False
    stop_after: 'inputs'
    debug: False
    first_id_filename: None
    defines: dictionary of defines, like {'chromeos': '1'}

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''
  handler = GrdContentHandler(stop_after=stop_after, debug=debug,
                              defines=defines)
  try:
    xml.sax.parse(filename_or_stream, handler)
  except StopParsingException:
    assert stop_after
    pass
  except:
    raise

  if not flexible_root or hasattr(handler.root, 'SetOwnDir'):
    assert isinstance(filename_or_stream, types.StringType) or dir != None
    if not dir:
      dir = util.dirname(filename_or_stream)
      if len(dir) == 0:
        dir = '.'
    # Fix up the base_dir so it is relative to the input file.
    handler.root.SetOwnDir(dir)

  # Assign first ids to the nodes that don't have them.
  if isinstance(handler.root, misc.GritNode) and first_id_filename != '':
    handler.root.AssignFirstIds(filename_or_stream, first_id_filename)

  return handler.root
Exemple #6
0
    def Run(self, opts, args):
        args = self.ParseOptions(args)
        if len(args) != 1:
            print(
                'This tool takes a single tool-specific argument, the path to the\n'
                '.rc file to process.')
            return 2
        self.SetOptions(opts)

        path = args[0]
        out_path = os.path.join(
            util.dirname(path),
            os.path.splitext(os.path.basename(path))[0] + '.grd')

        rcfile = util.WrapInputStream(file(path, 'r'), self.input_encoding)
        rctext = rcfile.read()

        grd_text = unicode(self.Process(rctext, path))

        rcfile.close()

        outfile = util.WrapOutputStream(file(out_path, 'w'), 'utf-8')
        outfile.write(grd_text)
        outfile.close()

        print 'Wrote output file %s.\nPlease check for TODO items in the file.' % out_path
Exemple #7
0
  def Run(self, opts, args):
    """Runs the Android2Grd tool.

    Inherited from grit.interface.Tool.

    Args:
      opts: List of string arguments that should be parsed.
      args: String containing the path of the strings.xml file to be converted.
    """
    args = self.ParseOptions(args)
    if len(args) != 1:
      print ('Tool requires one argument, a the path to a android '
             'strings.xml resource file to be converted.')
      return 2
    self.SetOptions(opts)

    android_path = args[0]
    if not self.name:
      self.name = 'android_strings'
    out_path = os.path.join(util.dirname(android_path),
                            self.name + '.grd')

    # Read and parse the Android strings.xml file.
    android_file = open(android_path)
    android_dom = parse(android_file)

    # Create the top level grit node and write it to a file in grd_dir
    grd_string = self.AndroidDOMToGRDString(android_dom)
    grd_filename = self.name + '.grd'
    grd_path = os.path.join(self.grd_dir, grd_filename)
    with open(grd_path, 'w') as grd_file:
      grd_file.write(grd_string)
Exemple #8
0
    def Run(self, opts, args):
        self.SetOptions(opts)

        limit_file = None
        limit_is_grd = False
        limit_file_dir = None
        limit_untranslated_lang = False
        own_opts, args = getopt.getopt(args, 'l:D:E:ihL')
        for key, val in own_opts:
            if key == '-l':
                limit_file = open(val, 'r')
                limit_file_dir = util.dirname(val)
                if not len(limit_file_dir):
                    limit_file_dir = '.'
                limit_is_grd = os.path.splitext(val)[1] == '.grd'
            elif key == '-i':
                self.format = self.FORMAT_IDS_ONLY
            elif key == '-L':
                limit_untranslated_lang = args[1:] if len(args) > 1 else False
            elif key == '-D':
                name, val = util.ParseDefine(val)
                self.defines[name] = val
            elif key == '-E':
                (env_name, env_value) = val.split('=', 1)
                os.environ[env_name] = env_value
        if not len(args) == 1 and not limit_untranslated_lang:
            print(
                'grit xmb takes exactly one argument, the path to the XMB file '
                'to output.')
            return 2

        xmb_path = args[0]
        res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose)
        res_tree.SetOutputLanguage('en')
        res_tree.SetDefines(self.defines)
        res_tree.OnlyTheseTranslations(limit_untranslated_lang or [])
        res_tree.RunGatherers()

        lang_jobs = []
        xmb_prefix, ext = os.path.splitext(xmb_path)
        for lang in limit_untranslated_lang or []:
            lang_jobs.append((lang, xmb_prefix + "_" + lang + ext))

        for lang, cur_xmb_path in lang_jobs or [(None, xmb_path)]:
            try:
                os.makedirs(os.path.dirname(cur_xmb_path))
            except:
                pass
            with open(cur_xmb_path, 'wb') as output_file:
                self.Process(res_tree,
                             output_file,
                             limit_file,
                             limit_is_grd,
                             limit_file_dir,
                             missing_translate_for_lang=lang)
        if limit_file:
            limit_file.close()
        print "Wrote %s" % xmb_path
Exemple #9
0
  def Process(self, rctext, rc_path):
    '''Processes 'rctext' and returns a resource tree corresponding to it.

    Args:
      rctext: complete text of the rc file
      rc_path: 'resource\resource.rc'

    Return:
      grit.node.base.Node subclass
    '''

    if self.pre_process:
      preprocess_class = util.NewClassInstance(self.pre_process,
                                               preprocess_interface.PreProcessor)
      if preprocess_class:
        rctext = preprocess_class.Process(rctext, rc_path)
      else:
        self.Out(
          'PreProcessing class could not be found. Skipping preprocessing.\n')

    # Start with a basic skeleton for the .grd file
    root = grd_reader.Parse(StringIO.StringIO(
      '''<?xml version="1.0" encoding="UTF-8"?>
      <grit base_dir="." latest_public_release="0"
          current_release="1" source_lang_id="en">
        <outputs />
        <translations />
        <release seq="1">
          <includes />
          <structures />
          <messages />
        </release>
      </grit>'''), util.dirname(rc_path))
    includes = root.children[2].children[0]
    structures = root.children[2].children[1]
    messages = root.children[2].children[2]
    assert (isinstance(includes, grit.node.empty.IncludesNode) and
            isinstance(structures, grit.node.empty.StructuresNode) and
            isinstance(messages, grit.node.empty.MessagesNode))

    self.AddIncludes(rctext, includes)
    self.AddStructures(rctext, structures, os.path.basename(rc_path))
    self.AddMessages(rctext, messages)

    self.VerboseOut('Validating that all IDs are unique...\n')
    root.ValidateUniqueIds()
    self.ExtraVerboseOut('Done validating that all IDs are unique.\n')

    if self.post_process:
      postprocess_class = util.NewClassInstance(self.post_process,
                                                postprocess_interface.PostProcessor)
      if postprocess_class:
        root = postprocess_class.Process(rctext, rc_path, root)
      else:
        self.Out(
          'PostProcessing class could not be found. Skipping postprocessing.\n')

    return root
Exemple #10
0
  def Run(self, opts, args):
    self.SetOptions(opts)

    limit_file = None
    limit_is_grd = False
    limit_file_dir = None
    limit_untranslated_lang = False
    own_opts, args = getopt.getopt(args, 'l:D:E:ihL')
    for key, val in own_opts:
      if key == '-l':
        limit_file = open(val, 'r')
        limit_file_dir = util.dirname(val)
        if not len(limit_file_dir):
          limit_file_dir = '.'
        limit_is_grd = os.path.splitext(val)[1] == '.grd'
      elif key == '-i':
        self.format = self.FORMAT_IDS_ONLY
      elif key == '-L':
        limit_untranslated_lang = args[1:] if len(args) > 1 else False 
      elif key == '-D':
        name, val = util.ParseDefine(val)
        self.defines[name] = val
      elif key == '-E':
        (env_name, env_value) = val.split('=', 1)
        os.environ[env_name] = env_value
    if not len(args) == 1 and not limit_untranslated_lang:
      print ('grit xmb takes exactly one argument, the path to the XMB file '
             'to output.')
      return 2

    xmb_path = args[0]
    res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose)
    res_tree.SetOutputLanguage('en')
    res_tree.SetDefines(self.defines)
    res_tree.OnlyTheseTranslations(limit_untranslated_lang or [])
    res_tree.RunGatherers()

    lang_jobs = []
    xmb_prefix, ext = os.path.splitext(xmb_path)
    for lang in limit_untranslated_lang or []:
        lang_jobs.append((lang, xmb_prefix+"_"+lang+ext))

    for lang, cur_xmb_path in lang_jobs or [(None, xmb_path)]:
      try:
        os.makedirs(os.path.dirname(cur_xmb_path))
      except:
        pass
      with open(cur_xmb_path, 'wb') as output_file:
        self.Process(
          res_tree, output_file, limit_file, limit_is_grd, limit_file_dir,
          missing_translate_for_lang= lang)
    if limit_file:
      limit_file.close()
    print "Wrote %s" % xmb_path
Exemple #11
0
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.OutputNode
      outfile: open filehandle
    '''
    base_dir = util.dirname(output_node.GetOutputFilename())

    formatter = GetFormatter(output_node.GetType())
    formatted = formatter(node, output_node.GetLanguage(), output_dir=base_dir)
    outfile.writelines(formatted)
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.OutputNode
      outfile: open filehandle
    '''
    base_dir = util.dirname(output_node.GetOutputFilename())

    formatter = GetFormatter(output_node.GetType())
    formatted = formatter(node, output_node.GetLanguage(), output_dir=base_dir)
    outfile.writelines(formatted)
Exemple #13
0
    def Run(self, opts, args):
        os.environ['cwd'] = os.getcwd()

        self.SetOptions(opts)

        limit_file = None
        limit_is_grd = False
        limit_file_dir = None
        own_opts, args = getopt.getopt(args, 'l:D:ih', ('help', ))
        for key, val in own_opts:
            if key == '-l':
                limit_file = open(val, 'r')
                limit_file_dir = util.dirname(val)
                if not len(limit_file_dir):
                    limit_file_dir = '.'
                limit_is_grd = os.path.splitext(val)[1] == '.grd'
            elif key == '-i':
                self.format = self.FORMAT_IDS_ONLY
            elif key == '-D':
                name, val = util.ParseDefine(val)
                self.defines[name] = val
            elif key == '-E':
                (env_name, env_value) = val.split('=', 1)
                os.environ[env_name] = env_value
            elif key == '--help':
                self.ShowUsage()
                sys.exit(0)
        if not len(args) == 1:
            print(
                'grit xmb takes exactly one argument, the path to the XMB file '
                'to output.')
            return 2

        xmb_path = args[0]
        res_tree = grd_reader.Parse(opts.input,
                                    debug=opts.extra_verbose,
                                    defines=self.defines)
        res_tree.SetOutputLanguage('en')
        res_tree.SetDefines(self.defines)
        res_tree.OnlyTheseTranslations([])
        res_tree.RunGatherers()

        with open(xmb_path, 'wb') as output_file:
            self.Process(res_tree, output_file, limit_file, limit_is_grd,
                         limit_file_dir)
        if limit_file:
            limit_file.close()
        print("Wrote %s" % xmb_path)
def _Emitter(target, source, env):
  '''A SCons emitter for .grd files, which modifies the list of targes to
  include all files in the <outputs> section of the .grd file as well as
  any other files output by 'grit build' for the .grd file.
  '''
  from grit import grd_reader
  from grit import util

  # TODO(gspencer):  Had to use .abspath, not str(target[0]), to get
  # this to work with Repository() directories.
  # Get this functionality folded back into the upstream grit tool.
  #base_dir = util.dirname(str(target[0]))
  base_dir = util.dirname(target[0].abspath)

  grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled())

  target = []
  lang_folders = {}
  # Add all explicitly-specified output files
  for output in grd.GetOutputFiles():
    path = os.path.join(base_dir, output.GetFilename())
    target.append(path)

    if path.endswith('.h'):
      path, filename = os.path.split(path)
    if _IsDebugEnabled():
      print "GRIT: Added target %s" % path
    if output.attrs['lang'] != '':
      lang_folders[output.attrs['lang']] = os.path.dirname(path)

  # Add all generated files, once for each output language.
  for node in grd:
    if node.name == 'structure':
      # TODO(joi) Should remove the "if sconsdep is true" thing as it is a
      # hack - see grit/node/structure.py
      if node.HasFileForLanguage() and node.attrs['sconsdep'] == 'true':
        for lang in lang_folders:
          path = node.FileForLanguage(lang, lang_folders[lang],
                                      create_file=False,
                                      return_if_not_generated=False)
          if path:
            target.append(path)
            if _IsDebugEnabled():
              print "GRIT: Added target %s" % path

  # return target and source lists
  return (target, source)
Exemple #15
0
  def Run(self, opts, args):
    args = self.ParseOptions(args)
    if len(args) != 1:
      print ('This tool takes a single tool-specific argument, the path to the\n'
             '.rc file to process.')
      return 2
    self.SetOptions(opts)

    path = args[0]
    out_path = os.path.join(util.dirname(path),
                os.path.splitext(os.path.basename(path))[0] + '.grd')

    rctext = util.ReadFile(path, self.input_encoding)
    grd_text = unicode(self.Process(rctext, path))
    with util.WrapOutputStream(file(out_path, 'w'), 'utf-8') as outfile:
      outfile.write(grd_text)

    print 'Wrote output file %s.\nPlease check for TODO items in the file.' % out_path
Exemple #16
0
  def Run(self, opts, args):
    args = self.ParseOptions(args)
    if len(args) != 1:
      print('This tool takes a single tool-specific argument, the path to the\n'
            '.rc file to process.')
      return 2
    self.SetOptions(opts)

    path = args[0]
    out_path = os.path.join(util.dirname(path),
                os.path.splitext(os.path.basename(path))[0] + '.grd')

    rctext = util.ReadFile(path, self.input_encoding)
    grd_text = six.text_type(self.Process(rctext, path))
    with util.WrapOutputStream(open(out_path, 'wb'), 'utf-8') as outfile:
      outfile.write(grd_text)

    print('Wrote output file %s.\nPlease check for TODO items in the file.' %
          (out_path,))
Exemple #17
0
  def Run(self, opts, args):
    self.SetOptions(opts)

    limit_file = None
    limit_is_grd = False
    limit_file_dir = None
    own_opts, args = getopt.getopt(args, 'l:D:ihp')
    for key, val in own_opts:
      if key == '-l':
        limit_file = open(val, 'r')
        limit_file_dir = util.dirname(val)
        if not len(limit_file_dir):
          limit_file_dir = '.'
        limit_is_grd = os.path.splitext(val)[1] == '.grd'
      elif key == '-i':
        self.format = self.FORMAT_IDS_ONLY
      elif key == '-p':
        self.format = self.FORMAT_POT
      elif key == '-D':
        name, val = util.ParseDefine(val)
        self.defines[name] = val
      elif key == '-E':
        (env_name, env_value) = val.split('=', 1)
        os.environ[env_name] = env_value
    if not len(args) == 1:
      print ('grit xmb takes exactly one argument, the path to the XMB file '
             'to output.')
      return 2

    xmb_path = args[0]
    res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose)
    res_tree.SetOutputLanguage('en')
    res_tree.SetDefines(self.defines)
    res_tree.OnlyTheseTranslations([])
    res_tree.RunGatherers()

    with open(xmb_path, 'wb') as output_file:
      self.Process(
        res_tree, output_file, limit_file, limit_is_grd, limit_file_dir)
    if limit_file:
      limit_file.close()
    print "Wrote %s" % xmb_path
Exemple #18
0
    def ProcessNode(node, output_node, outfile):
        '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.File
      outfile: open filehandle
    '''
        # See if the node should be skipped by a whitelist.
        # Note: Some Format calls have side effects, so Format is always called
        # and the whitelist is used to only avoid the output.
        should_write = not node.WhitelistMarkedAsSkip()

        base_dir = util.dirname(output_node.GetOutputFilename())

        try:
            formatter = node.ItemFormatter(output_node.GetType())
            if formatter:
                formatted = formatter.Format(node,
                                             output_node.GetLanguage(),
                                             output_dir=base_dir)
                if should_write:
                    outfile.write(formatted)
        except:
            print u'Error processing node %s' % unicode(node)
            raise

        for child in node.children:
            RcBuilder.ProcessNode(child, output_node, outfile)

        try:
            if formatter:
                formatted = formatter.FormatEnd(node,
                                                output_node.GetLanguage(),
                                                output_dir=base_dir)
                if should_write:
                    outfile.write(formatted)
        except:
            print u'Error processing node %s' % unicode(node)
            raise
Exemple #19
0
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.OutputNode
      outfile: open filehandle
    '''
    base_dir = util.dirname(output_node.GetOutputFilename())

    formatter = GetFormatter(output_node.GetType())
    formatted = formatter(node, output_node.GetLanguage(), output_dir=base_dir)
    outfile.writelines(formatted)
    if output_node.GetType() == 'data_package':
      with open(output_node.GetOutputFilename() + '.info', 'w') as infofile:
        if node.info:
          # We terminate with a newline so that when these files are
          # concatenated later we consistently terminate with a newline so
          # consumers can account for terminating newlines.
          infofile.writelines(['\n'.join(node.info), '\n'])
Exemple #20
0
def _Emitter(target, source, env):
    """A SCons emitter for .grd files, which modifies the list of targes to
  include all files in the <outputs> section of the .grd file as well as
  any other files output by 'grit build' for the .grd file.
  """
    from grit import util
    from grit import grd_reader

    base_dir = util.dirname(str(target[0]))

    grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled())

    target = []
    lang_folders = {}
    # Add all explicitly-specified output files
    for output in grd.GetOutputFiles():
        path = os.path.join(base_dir, output.GetFilename())
        target.append(path)
        if _IsDebugEnabled():
            print "GRIT: Added target %s" % path
        if output.attrs["lang"] != "":
            lang_folders[output.attrs["lang"]] = os.path.dirname(path)

    # Add all generated files, once for each output language.
    for node in grd:
        if node.name == "structure":
            # TODO(joi) Should remove the "if sconsdep is true" thing as it is a
            # hack - see grit/node/structure.py
            if node.HasFileForLanguage() and node.attrs["sconsdep"] == "true":
                for lang in lang_folders:
                    path = node.FileForLanguage(
                        lang, lang_folders[lang], create_file=False, return_if_not_generated=False
                    )
                    if path:
                        target.append(path)
                        if _IsDebugEnabled():
                            print "GRIT: Added target %s" % path

    # return target and source lists
    return (target, source)
Exemple #21
0
def _Emitter(target, source, env):
  """Modifies the list of targets to include all outputs.

  Note that this also sets up the dependencies, even though it's an emitter
  rather than a scanner.  This is so that the resource header file doesn't show
  as having dependencies.

  Args:
    target: The list of targets to emit for.
    source: The source or list of sources for the target.
    env: The SCons environment.

  Returns:
    A tuple of (targets, sources).
  """
  from grit import grd_reader
  from grit import util

  (defines, res_file) = _ParseRcFlags(env['RCFLAGS'])

  grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled())
  # TODO(jperkins): This is a hack to get an output context set for the reader.
  # This should really be smarter about the language.
  grd.SetOutputLanguage('en')
  grd.SetDefines(defines)

  base_dir = util.dirname(str(target[0]))
  (rc_headers, rc_alls, lang_folders) = _GetOutputFiles(grd, base_dir)
  (structure_outputs, translated_files, static_files) = _ProcessNodes(grd,
      base_dir, lang_folders)

  rc_alls.extend(structure_outputs)
  _SetDependencies(env, base_dir, res_file, rc_alls, translated_files,
                   static_files)

  targets = rc_headers
  targets.extend(rc_alls)

  # Return target and source lists.
  return (targets, source)
Exemple #22
0
def _Emitter(target, source, env):
    """Modifies the list of targets to include all outputs.

  Note that this also sets up the dependencies, even though it's an emitter
  rather than a scanner.  This is so that the resource header file doesn't show
  as having dependencies.

  Args:
    target: The list of targets to emit for.
    source: The source or list of sources for the target.
    env: The SCons environment.

  Returns:
    A tuple of (targets, sources).
  """
    from grit import grd_reader
    from grit import util

    (defines, res_file) = _ParseRcFlags(env['RCFLAGS'])

    grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled())
    # TODO(jperkins): This is a hack to get an output context set for the reader.
    # This should really be smarter about the language.
    grd.SetOutputLanguage('en')
    grd.SetDefines(defines)

    base_dir = util.dirname(str(target[0]))
    (rc_headers, rc_alls, lang_folders) = _GetOutputFiles(grd, base_dir)
    (structure_outputs, translated_files,
     static_files) = _ProcessNodes(grd, base_dir, lang_folders)

    rc_alls.extend(structure_outputs)
    _SetDependencies(env, base_dir, res_file, rc_alls, translated_files,
                     static_files)

    targets = rc_headers
    targets.extend(rc_alls)

    # Return target and source lists.
    return (targets, source)
  def ProcessNode(node, output_node, outfile):
    '''Processes a node in-order, calling its formatter before and after
    recursing to its children.

    Args:
      node: grit.node.base.Node subclass
      output_node: grit.node.io.File
      outfile: open filehandle
    '''
    # See if the node should be skipped by a whitelist.
    # Note: Some Format calls have side effects, so Format is always called
    # and the whitelist is used to only avoid the output.
    should_write = not node.WhitelistMarkedAsSkip()

    base_dir = util.dirname(output_node.GetOutputFilename())

    try:
      formatter = node.ItemFormatter(output_node.GetType())
      if formatter:
        formatted = formatter.Format(node, output_node.GetLanguage(),
                                     begin_item=True, output_dir=base_dir)
        if should_write:
          outfile.write(formatted)
    except:
      print u"Error processing node %s" % unicode(node)
      raise

    for child in node.children:
      RcBuilder.ProcessNode(child, output_node, outfile)

    try:
      if formatter:
        formatted = formatter.Format(node, output_node.GetLanguage(),
                                     begin_item=False, output_dir=base_dir)
        if should_write:
          outfile.write(formatted)
    except:
      print u"Error processing node %s" % unicode(node)
      raise
Exemple #24
0
def Parse(filename_or_stream, dir=None, stop_after=None, first_ids_file=None,
          debug=False, defines=None, tags_to_ignore=None):
  '''Parses a GRD file into a tree of nodes (from grit.node).

  If filename_or_stream is a stream, 'dir' should point to the directory
  notionally containing the stream (this feature is only used in unit tests).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If 'first_ids_file' is non-empty, it is used to override the setting
  for the first_ids_file attribute of the <grit> root node.

  Args:
    filename_or_stream: './bla.xml'
    dir: None (if filename_or_stream is a filename) or '.'
    stop_after: 'inputs'
    first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
    debug: False
    defines: dictionary of defines, like {'chromeos': '1'}

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''

  if dir is None and isinstance(filename_or_stream, types.StringType):
    dir = util.dirname(filename_or_stream)

  handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir,
                              defines=defines, tags_to_ignore=tags_to_ignore)
  try:
    xml.sax.parse(filename_or_stream, handler)
  except StopParsingException:
    assert stop_after
    pass
  except:
    if not debug:
      print "parse exception: run GRIT with the -x flag to debug .grd problems"
    raise

  if handler.root.name != 'grit':
    raise exception.MissingElement("root tag must be <grit>")

  if hasattr(handler.root, 'SetOwnDir'):
    # Fix up the base_dir so it is relative to the input file.
    assert dir is not None
    handler.root.SetOwnDir(dir)

  if isinstance(handler.root, misc.GritNode):
    if first_ids_file:
      handler.root.attrs['first_ids_file'] = first_ids_file
    # Assign first ids to the nodes that don't have them.
    handler.root.AssignFirstIds(filename_or_stream, defines)

  return handler.root
Exemple #25
0
def Parse(filename_or_stream,
          dir=None,
          stop_after=None,
          first_ids_file=None,
          debug=False,
          defines=None,
          tags_to_ignore=None,
          target_platform=None,
          predetermined_ids_file=None):
    '''Parses a GRD file into a tree of nodes (from grit.node).

  If filename_or_stream is a stream, 'dir' should point to the directory
  notionally containing the stream (this feature is only used in unit tests).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If 'first_ids_file' is non-empty, it is used to override the setting for the
  first_ids_file attribute of the <grit> root node. Note that the first_ids_file
  parameter should be relative to the cwd, even though the first_ids_file
  attribute of the <grit> node is relative to the grd file.

  If 'target_platform' is set, this is used to determine the target
  platform of builds, instead of using |sys.platform|.

  Args:
    filename_or_stream: './bla.xml'
    dir: None (if filename_or_stream is a filename) or '.'
    stop_after: 'inputs'
    first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
    debug: False
    defines: dictionary of defines, like {'chromeos': '1'}
    target_platform: None or the value that would be returned by sys.platform
        on your target platform.
    predetermined_ids_file: File path to a file containing a pre-determined
        mapping from resource names to resource ids which will be used to assign
        resource ids to those resources.

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''

    if isinstance(filename_or_stream, six.string_types):
        source = filename_or_stream
        if dir is None:
            dir = util.dirname(filename_or_stream)
    else:
        source = None

    handler = GrdContentHandler(stop_after=stop_after,
                                debug=debug,
                                dir=dir,
                                defines=defines,
                                tags_to_ignore=tags_to_ignore,
                                target_platform=target_platform,
                                source=source)
    try:
        xml.sax.parse(filename_or_stream, handler)
    except StopParsingException:
        assert stop_after
        pass
    except:
        if not debug:
            print(
                "parse exception: run GRIT with the -x flag to debug .grd problems"
            )
        raise

    if handler.root.name != 'grit':
        raise exception.MissingElement("root tag must be <grit>")

    if hasattr(handler.root, 'SetOwnDir'):
        # Fix up the base_dir so it is relative to the input file.
        assert dir is not None
        handler.root.SetOwnDir(dir)

    if isinstance(handler.root, misc.GritNode):
        handler.root.SetPredeterminedIdsFile(predetermined_ids_file)
        if first_ids_file:
            # Make the path to the first_ids_file relative to the grd file,
            # unless it begins with GRIT_DIR.
            GRIT_DIR_PREFIX = 'GRIT_DIR'
            if not (first_ids_file.startswith(GRIT_DIR_PREFIX)
                    and first_ids_file[len(GRIT_DIR_PREFIX)] in ['/', '\\']):
                rel_dir = os.path.relpath(os.getcwd(), dir)
                first_ids_file = util.normpath(
                    os.path.join(rel_dir, first_ids_file))
            handler.root.attrs['first_ids_file'] = first_ids_file
        # Assign first ids to the nodes that don't have them.
        handler.root.AssignFirstIds(filename_or_stream, defines)

    return handler.root
Exemple #26
0
def Parse(filename_or_stream, dir=None, flexible_root=False,
          stop_after=None, first_ids_file=None, debug=False,
          defines=None, tags_to_ignore=None):
  '''Parses a GRD file into a tree of nodes (from grit.node).

  If flexible_root is False, the root node must be a <grit> element.  Otherwise
  it can be any element.  The "own" directory of the file will only be fixed up
  if the root node is a <grit> element.

  'dir' should point to the directory of the input file, or be the full path
  to the input file (the filename will be stripped).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If 'first_ids_file' is non-empty, it is used to override the setting
  for the first_ids_file attribute of the <grit> root node.

  Args:
    filename_or_stream: './bla.xml'  (must be filename if dir is None)
    dir: '.' or None (only if filename_or_stream is a filename)
    flexible_root: True | False
    stop_after: 'inputs'
    first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
    debug: False
    defines: dictionary of defines, like {'chromeos': '1'}

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''
  handler = GrdContentHandler(stop_after=stop_after, debug=debug,
                              defines=defines, tags_to_ignore=tags_to_ignore)
  try:
    xml.sax.parse(filename_or_stream, handler)
  except StopParsingException:
    assert stop_after
    pass
  except:
    if not debug:
      print "parse exception: run GRIT with the -x flag to debug .grd problems"
    raise

  if not flexible_root or hasattr(handler.root, 'SetOwnDir'):
    assert isinstance(filename_or_stream, types.StringType) or dir != None
    if not dir:
      dir = util.dirname(filename_or_stream)
      if len(dir) == 0:
        dir = '.'
    # Fix up the base_dir so it is relative to the input file.
    handler.root.SetOwnDir(dir)

  if isinstance(handler.root, misc.GritNode):
    if first_ids_file:
      handler.root.attrs['first_ids_file'] = first_ids_file
    # Assign first ids to the nodes that don't have them.
    handler.root.AssignFirstIds(filename_or_stream, defines)

  return handler.root
Exemple #27
0
def Parse(filename_or_stream, dir=None, stop_after=None, first_ids_file=None,
          debug=False, defines=None, tags_to_ignore=None, target_platform=None):
  '''Parses a GRD file into a tree of nodes (from grit.node).

  If filename_or_stream is a stream, 'dir' should point to the directory
  notionally containing the stream (this feature is only used in unit tests).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If 'first_ids_file' is non-empty, it is used to override the setting for the
  first_ids_file attribute of the <grit> root node. Note that the first_ids_file
  parameter should be relative to the cwd, even though the first_ids_file
  attribute of the <grit> node is relative to the grd file.

  If 'target_platform' is set, this is used to determine the target
  platform of builds, instead of using |sys.platform|.

  Args:
    filename_or_stream: './bla.xml'
    dir: None (if filename_or_stream is a filename) or '.'
    stop_after: 'inputs'
    first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
    debug: False
    defines: dictionary of defines, like {'chromeos': '1'}
    target_platform: None or the value that would be returned by sys.platform
        on your target platform.

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''

  if dir is None and isinstance(filename_or_stream, types.StringType):
    dir = util.dirname(filename_or_stream)

  handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir,
                              defines=defines, tags_to_ignore=tags_to_ignore,
                              target_platform=target_platform)
  try:
    xml.sax.parse(filename_or_stream, handler)
  except StopParsingException:
    assert stop_after
    pass
  except:
    if not debug:
      print "parse exception: run GRIT with the -x flag to debug .grd problems"
    raise

  if handler.root.name != 'grit':
    raise exception.MissingElement("root tag must be <grit>")

  if hasattr(handler.root, 'SetOwnDir'):
    # Fix up the base_dir so it is relative to the input file.
    assert dir is not None
    handler.root.SetOwnDir(dir)

  if isinstance(handler.root, misc.GritNode):
    if first_ids_file:
      # Make the path to the first_ids_file relative to the grd file,
      # unless it begins with GRIT_DIR.
      GRIT_DIR_PREFIX = 'GRIT_DIR'
      if not (first_ids_file.startswith(GRIT_DIR_PREFIX)
          and first_ids_file[len(GRIT_DIR_PREFIX)] in ['/', '\\']):
        rel_dir = os.path.relpath(os.getcwd(), dir)
        first_ids_file = util.normpath(os.path.join(rel_dir, first_ids_file))
      handler.root.attrs['first_ids_file'] = first_ids_file
    # Assign first ids to the nodes that don't have them.
    handler.root.AssignFirstIds(filename_or_stream, defines)

  return handler.root
Exemple #28
0
def Parse(filename_or_stream,
          dir=None,
          flexible_root=False,
          stop_after=None,
          first_ids_file=None,
          debug=False,
          defines=None,
          tags_to_ignore=None):
    '''Parses a GRD file into a tree of nodes (from grit.node).

  If flexible_root is False, the root node must be a <grit> element.  Otherwise
  it can be any element.  The "own" directory of the file will only be fixed up
  if the root node is a <grit> element.

  'dir' should point to the directory of the input file, or be the full path
  to the input file (the filename will be stripped).

  If 'stop_after' is provided, the parsing will stop once the first node
  with this name has been fully parsed (including all its contents).

  If 'debug' is true, lots of information about the parsing events will be
  printed out during parsing of the file.

  If 'first_ids_file' is non-empty, it is used to override the setting
  for the first_ids_file attribute of the <grit> root node.

  Args:
    filename_or_stream: './bla.xml'  (must be filename if dir is None)
    dir: '.' or None (only if filename_or_stream is a filename)
    flexible_root: True | False
    stop_after: 'inputs'
    first_ids_file: 'GRIT_DIR/../gritsettings/resource_ids'
    debug: False
    defines: dictionary of defines, like {'chromeos': '1'}

  Return:
    Subclass of grit.node.base.Node

  Throws:
    grit.exception.Parsing
  '''
    handler = GrdContentHandler(stop_after=stop_after,
                                debug=debug,
                                defines=defines,
                                tags_to_ignore=tags_to_ignore)
    try:
        xml.sax.parse(filename_or_stream, handler)
    except StopParsingException:
        assert stop_after
        pass
    except:
        if not debug:
            print "parse exception: run GRIT with the -x flag to debug .grd problems"
        raise

    if not flexible_root or hasattr(handler.root, 'SetOwnDir'):
        assert isinstance(filename_or_stream, types.StringType) or dir != None
        if not dir:
            dir = util.dirname(filename_or_stream)
            if len(dir) == 0:
                dir = '.'
        # Fix up the base_dir so it is relative to the input file.
        handler.root.SetOwnDir(dir)

    if isinstance(handler.root, misc.GritNode):
        if first_ids_file:
            handler.root.attrs['first_ids_file'] = first_ids_file
        # Assign first ids to the nodes that don't have them.
        handler.root.AssignFirstIds(filename_or_stream, defines)

    return handler.root