lib/pbxproject/pbxproject.rb
def parse
      raise "Not ready for parsing" unless @state == :ready
      pbx = File.open(@filename, 'r')
    
      line_num = 0
      group_name = []
      # group = []
      section_type = nil
      section = nil
      item = nil
      list_name = nil
      list = nil
      grouplist_name = nil
      grouplist = nil
    
      # Read our file
      pbx.each_line do |line|
        if (line_num == 0 && !line.match(Regexp.new(Regexp.escape('// !$*UTF8*$!'))))
          raise "Unknown file format"
        end
      
        # Main level Attributes
        if (group_name.count == 0 && !section_type && m = line.match(/\s+(.*?) = (.*?)( \/\* (.*) \*\/)?;/))
          # d = { :value => m[2], :comment => m[4] }
          self.instance_variable_set("@#{m[1]}", PBXTypes::BasicValue.new(:value => m[2], :comment => m[4]))
        
          next
        end
      
        # Begin object group
        if (m = line.match(/\s+(.*) = \{/))
          group_name.push m[1]
          # group.push {}
        end
      
        # End our object group
        if (line.match(/\s+\};/))
          group_name.pop
          # group.pop
        
          if (item && group_name.count < 2)
            @sections[section_type].push item
            item = nil
          end
        end
      
        # Begin section
        if (m = line.match(/\/\* Begin (.*) section \*\//))
          section_type = m[1]
          @sections[section_type] = []

          next
        end
      
        # One line section data, simple. huh?
        if (section_type && group_name.count < 3 && m = line.match(/\s+(.*?) (\/\* (.*?) \*\/ )?= \{(.*)\};/))
          begin
            # cls = PBXProject::PBXProject::const_get(section_type)
            # item = cls.new
            item = eval("PBXTypes::#{section_type}").new
        
            item.guid = m[1]
            item.comment = m[3]
            # m[4].scan(/(.*?) = (.*?)( \/\* (.*) \*\/)?; ?/).each do |v|
            # 1: name
            # 2: value
            # 3: /* comment */
            # 4: comment
            m[4].scan(/(\S*?) = (\s*?(.*?)(?:(?={){[^}]*}|(?: \/\* (.*?) \*\/)?(?=;)))/).each do |v|
              if (v[3])
                # d = { :value => v[1], :comment => v[3]}
                item.instance_variable_set("@#{v[0]}", PBXTypes::BasicValue.new(:value => v[2], :comment => v[3]))
              else
                item.instance_variable_set("@#{v[0]}", v[1][/^{/] ? v[1] : v[2])
              end
            end
        
            @sections[section_type].push item
            item = nil
          rescue NameError => e
            puts e.inspect
          end
        
          next
        end
      
        # Multiline with lists
        if (section_type && group_name.count < 3 && m = line.match(/\s+(.*?) (\/\* (.*?) \*\/ )?= \{/))
          begin
            # cls = PBXProject::PBXProject::const_get(section_type)
            # item = cls.new
            item = eval("PBXTypes::#{section_type}").new
          
            item.guid = m[1]
            item.comment = m[3]
          
            # puts item.inspect
          rescue NameError => e
            puts e.inspect
          end
        
          next
        end
      
        # Next line in multiline
        if (item && m = line.match(/^\s*(.*?) = (.*?)(?: \/\* (.*) \*\/)?;$/))
          if (group_name.count < 3)
            # i = { :value => m[2], :comment => m[3] }
            item.instance_variable_set("@#{m[1]}", PBXTypes::BasicValue.new(:value => m[2], :comment => m[3]))
          else
            grp = item.instance_variable_get("@#{group_name.last}")
            if (!grp.kind_of?(Hash))
              grp = {}
            end
            # grp[m[1]] = { :value => m[2], :comment => m[3] }
            grp[m[1]] = PBXTypes::BasicValue.new :value => m[2], :comment => m[3]
            item.instance_variable_set("@#{group_name.last}", grp)
          end
        
          next
        end
      
        # And the multiline list begin
        if (item && m = line.match(/\s+(.*?) = \(/))
          if (group_name.count < 3)
            list_name = m[1]
            list = []
          else
            grouplist_name = m[1]
            grouplist = []
          end
        
          next
        end
      
        # And list items
        if (item && m = line.match(/\s+(.*?)( \/\* (.*?) \*\/)?,/))
          if (group_name.count < 3)
            # i = { :item => m[1], :comment => m[3] }
            list.push PBXTypes::BasicValue.new :value => m[1], :comment => m[3]
          else
            # i = { :item => m[1], :comment => m[3] }
            grouplist.push PBXTypes::BasicValue.new :value => m[1], :comment => m[3]
          end
        
          next
        end
      
        if (item && line.match(/\s+\);/))
          if (group_name.count < 3)
            item.instance_variable_set("@#{list_name}", list)
            list = nil
            list_name = nil
          else
            grp = item.instance_variable_get("@#{group_name.last}")
            if (!grp.kind_of?(Hash))
              grp = {}
            end
            grp[grouplist_name] = grouplist
            item.instance_variable_set("@#{group_name.last}", grp)
            grouplist_name = nil
            grouplist = nil
          end
        
          next
        end
      
        # End section
        if (m = line.match(/\/\* End (.*) section \*\//))
          section_type = nil
          section = nil
        end
      
        # Increse our line counter
        line_num += 1
      end
    
      @state = :parsed
    
      true
    end
def parse
      raise "Not ready for parsing" unless @state == :ready
      pbx = File.open(@filename, 'r')
    
      line_num = 0
      group_name = []
      # group = []
      section_type = nil
      section = nil
      item = nil
      list_name = nil
      list = nil
      grouplist_name = nil
      grouplist = nil
    
      # Read our file
      pbx.each_line do |line|
        if (line_num == 0 && !line.match(Regexp.new(Regexp.escape('// !$*UTF8*$!'))))
          raise "Unknown file format"
        end
      
        # Main level Attributes
        if (group_name.count == 0 && !section_type && m = line.match(/\s+(.*?) = (.*?)( \/\* (.*) \*\/)?;/))
          # d = { :value => m[2], :comment => m[4] }
          self.instance_variable_set("@#{m[1]}", PBXTypes::BasicValue.new(:value => m[2], :comment => m[4]))
        
          next
        end
      
        # Begin object group
        if (m = line.match(/\s+(.*) = \{/))
          group_name.push m[1]
          # group.push {}
        end
      
        # End our object group
        if (line.match(/\s+\};/))
          group_name.pop
          # group.pop
        
          if (item && group_name.count < 2)
            @sections[section_type].push item
            item = nil
          end
        end
      
        # Begin section
        if (m = line.match(/\/\* Begin (.*) section \*\//))
          section_type = m[1]
          @sections[section_type] = []

          next
        end
      
        # One line section data, simple. huh?
        if (section_type && group_name.count < 3 && m = line.match(/\s+(.*?) (\/\* (.*?) \*\/ )?= \{(.*)\};/))
          begin
            # cls = PBXProject::PBXProject::const_get(section_type)
            # item = cls.new
            item = eval("PBXTypes::#{section_type}").new
        
            item.guid = m[1]
            item.comment = m[3]
            # m[4].scan(/(.*?) = (.*?)( \/\* (.*) \*\/)?; ?/).each do |v|
            # 1: name
            # 2: value
            # 3: /* comment */
            # 4: comment
            m[4].scan(/(\S*?) = (\s*?(.*?)(?:(?={){[^}]*}|(?: \/\* (.*?) \*\/)?(?=;)))/).each do |v|
              if (v[3])
                # d = { :value => v[1], :comment => v[3]}
                item.instance_variable_set("@#{v[0]}", PBXTypes::BasicValue.new(:value => v[2], :comment => v[3]))
              else
                item.instance_variable_set("@#{v[0]}", v[1][/^{/] ? v[1] : v[2])
              end
            end
        
            @sections[section_type].push item
            item = nil
          rescue NameError => e
            puts e.inspect
          end
        
          next
        end
      
        # Multiline with lists
        if (section_type && group_name.count < 3 && m = line.match(/\s+(.*?) (\/\* (.*?) \*\/ )?= \{/))
          begin
            # cls = PBXProject::PBXProject::const_get(section_type)
            # item = cls.new
            item = eval("PBXTypes::#{section_type}").new
          
            item.guid = m[1]
            item.comment = m[3]
          
            # puts item.inspect
          rescue NameError => e
            puts e.inspect
          end
        
          next
        end
      
        # Next line in multiline
        if (item && m = line.match(/^\s*(.*?) = (.*?)(?: \/\* (.*) \*\/)?;$/))
          if (group_name.count < 3)
            # i = { :value => m[2], :comment => m[3] }
            item.instance_variable_set("@#{m[1]}", PBXTypes::BasicValue.new(:value => m[2], :comment => m[3]))
          else
            grp = item.instance_variable_get("@#{group_name.last}")
            if (!grp.kind_of?(Hash))
              grp = {}
            end
            # grp[m[1]] = { :value => m[2], :comment => m[3] }
            grp[m[1]] = PBXTypes::BasicValue.new :value => m[2], :comment => m[3]
            item.instance_variable_set("@#{group_name.last}", grp)
          end
        
          next
        end
      
        # And the multiline list begin
        if (item && m = line.match(/\s+(.*?) = \(/))
          if (group_name.count < 3)
            list_name = m[1]
            list = []
          else
            grouplist_name = m[1]
            grouplist = []
          end
        
          next
        end
      
        # And list items
        if (item && m = line.match(/\s+(.*?)( \/\* (.*?) \*\/)?,/))
          if (group_name.count < 3)
            # i = { :item => m[1], :comment => m[3] }
            list.push PBXTypes::BasicValue.new :value => m[1], :comment => m[3]
          else
            # i = { :item => m[1], :comment => m[3] }
            grouplist.push PBXTypes::BasicValue.new :value => m[1], :comment => m[3]
          end
        
          next
        end
      
        if (item && line.match(/\s+\);/))
          if (group_name.count < 3)
            item.instance_variable_set("@#{list_name}", list)
            list = nil
            list_name = nil
          else
            grp = item.instance_variable_get("@#{group_name.last}")
            if (!grp.kind_of?(Hash))
              grp = {}
            end
            grp[grouplist_name] = grouplist
            item.instance_variable_set("@#{group_name.last}", grp)
            grouplist_name = nil
            grouplist = nil
          end
        
          next
        end
      
        # End section
        if (m = line.match(/\/\* End (.*) section \*\//))
          section_type = nil
          section = nil
        end
      
        # Increse our line counter
        line_num += 1
      end
    
      @state = :parsed
    
      true
    end
def parse raise "Not ready for parsing" unless @state == :ready pbx = File . open ( @filename , 'r' ) line_num = 0 group_name = [ ] # group = [] section_type = nil section = nil item = nil list_name = nil list = nil grouplist_name = nil grouplist = nil # Read our file pbx . each_line do | line | if ( line_num == 0 && ! line . match ( Regexp . new ( Regexp . escape ( '// !$*UTF8*$!' ) ) ) ) raise "Unknown file format" end # Main level Attributes if ( group_name . count == 0 && ! section_type && m = line . match ( / \s \/ \* \* \/ / ) ) # d = { :value => m[2], :comment => m[4] } self . instance_variable_set ( "@#{m[1]}" , PBXTypes :: BasicValue . new ( :value => m [ 2 ] , :comment => m [ 4 ] ) ) next end # Begin object group if ( m = line . match ( / \s \{ / ) ) group_name . push m [ 1 ] # group.push {} end # End our object group if ( line . match ( / \s \} / ) ) group_name . pop # group.pop if ( item && group_name . count < 2 ) @sections [ section_type ] . push item item = nil end end # Begin section if ( m = line . match ( / \/ \* \* \/ / ) ) section_type = m [ 1 ] @sections [ section_type ] = [ ] next end # One line section data, simple. huh? if ( section_type && group_name . count < 3 && m = line . match ( / \s \/ \* \* \/ \{ \} / ) ) begin # cls = PBXProject::PBXProject::const_get(section_type) # item = cls.new item = eval ( "PBXTypes::#{section_type}" ) . new item . guid = m [ 1 ] item . comment = m [ 3 ] # m[4].scan(/(.*?) = (.*?)( \/\* (.*) \*\/)?; ?/).each do |v| # 1: name # 2: value # 3: /* comment */ # 4: comment m [ 4 ] . scan ( / \S \s \/ \* \* \/ / ) . each do | v | if ( v [ 3 ] ) # d = { :value => v[1], :comment => v[3]} item . instance_variable_set ( "@#{v[0]}" , PBXTypes :: BasicValue . new ( :value => v [ 2 ] , :comment => v [ 3 ] ) ) else item . instance_variable_set ( "@#{v[0]}" , v [ 1 ] [ / / ] ? v [ 1 ] : v [ 2 ] ) end end @sections [ section_type ] . push item item = nil rescue NameError => e puts e . inspect end next end # Multiline with lists if ( section_type && group_name . count < 3 && m = line . match ( / \s \/ \* \* \/ \{ / ) ) begin # cls = PBXProject::PBXProject::const_get(section_type) # item = cls.new item = eval ( "PBXTypes::#{section_type}" ) . new item . guid = m [ 1 ] item . comment = m [ 3 ] # puts item.inspect rescue NameError => e puts e . inspect end next end # Next line in multiline if ( item && m = line . match ( / \s \/ \* \* \/ / ) ) if ( group_name . count < 3 ) # i = { :value => m[2], :comment => m[3] } item . instance_variable_set ( "@#{m[1]}" , PBXTypes :: BasicValue . new ( :value => m [ 2 ] , :comment => m [ 3 ] ) ) else grp = item . instance_variable_get ( "@#{group_name.last}" ) if ( ! grp . kind_of? ( Hash ) ) grp = { } end # grp[m[1]] = { :value => m[2], :comment => m[3] } grp [ m [ 1 ] ] = PBXTypes :: BasicValue . new :value => m [ 2 ] , :comment => m [ 3 ] item . instance_variable_set ( "@#{group_name.last}" , grp ) end next end # And the multiline list begin if ( item && m = line . match ( / \s \( / ) ) if ( group_name . count < 3 ) list_name = m [ 1 ] list = [ ] else grouplist_name = m [ 1 ] grouplist = [ ] end next end # And list items if ( item && m = line . match ( / \s \/ \* \* \/ / ) ) if ( group_name . count < 3 ) # i = { :item => m[1], :comment => m[3] } list . push PBXTypes :: BasicValue . new :value => m [ 1 ] , :comment => m [ 3 ] else # i = { :item => m[1], :comment => m[3] } grouplist . push PBXTypes :: BasicValue . new :value => m [ 1 ] , :comment => m [ 3 ] end next end if ( item && line . match ( / \s \) / ) ) if ( group_name . count < 3 ) item . instance_variable_set ( "@#{list_name}" , list ) list = nil list_name = nil else grp = item . instance_variable_get ( "@#{group_name.last}" ) if ( ! grp . kind_of? ( Hash ) ) grp = { } end grp [ grouplist_name ] = grouplist item . instance_variable_set ( "@#{group_name.last}" , grp ) grouplist_name = nil grouplist = nil end next end # End section if ( m = line . match ( / \/ \* \* \/ / ) ) section_type = nil section = nil end # Increse our line counter line_num += 1 end @state = :parsed true end
This is one big parser
This is one big parser