OpenCores
URL https://opencores.org/ocsvn/soc_maker/soc_maker/trunk

Subversion Repositories soc_maker

[/] [soc_maker/] [trunk/] [lib/] [soc_maker.rb] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

###############################################################
#   
#  File:      soc_maker.rb
#
#  Author:    Christian Hättich
#
#  Project:   System-On-Chip Maker
#
#  Target:    Linux / Windows / Mac
#
#  Language:  ruby
#
#
###############################################################
#
#
#   Copyright (C) 2014  Christian Hättich  - feddischson [ at ] opencores.org
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
###############################################################
#
#   Description:
#     This part of the SOCMaker module contains
#       - initialization of
#         - logger
#         - configuration
#         - library
#         (see SOCMaker::load)
#       - creating objects from YAML files/strings
#         (see from_f, from_s)
#       - creating YAML files from objects
#         (see SOCMaker::YAML_EXT::write_yaml)
#       - error-types and functions
#         (see SOCMaker::ERR)
#   
#
#
###############################################################
require 'logger'
require 'yaml'
require 'digest/md5'
require 'fileutils'


# from
# http://stackoverflow.com/questions/2281490/how-to-add-a-custom-log-level-to-logger-in-ruby
class Logger
  def self.custom_level(tag)
    SEV_LABEL << tag 
    idx = SEV_LABEL.size - 1 

    define_method(tag.downcase.gsub(/\W+/, '_').to_sym) do |progname, &block|
      add(idx, nil, progname, &block)
    end 
  end 
  # add processing log level
  custom_level 'PROC'
end




module SOCMaker

  
  class << self
    public
    attr_accessor :logger
    attr_accessor :conf
    attr_accessor :lib
    def load( options={} )
      options = { skip_refresh: false, logger_out: STDOUT }.merge( options )
      @conf   = Conf::instance
      @logger = Logger.new(options[ :logger_out ] )
      @lib    = Lib.new()
      @logger.progname = @conf[ :app_name ]
      @lib.refresh( options[ :libpath ] ) unless options[ :skip_refresh ]
    end

    #
    # loading from from a YAML string
    # 
    def from_s( s )
      
      objs = []
      SOCMaker::YPP.to_yaml( s ) do |yaml_obj_str|

        begin
          YAML::load( yaml_obj_str )
          o = YAML::load( yaml_obj_str )

          # ensure, that we load only our classes
          if SOCMaker::conf[ :yaml_classes ].include?( o.class )
            o.verify
            objs << o
          else
            SOCMaker::logger.warn( "Tried to load something, which does not belong to #{SOCMaker::conf[ :app_name ]}" )
          end
        rescue ArgumentError, Psych::SyntaxError #=> e
          #p e
          SOCMaker::logger.error( 'YAML loading failed, invalid YAML syntax?' )
          raise ERR::YAMLParseError
        else
        end
      end

      if block_given?
        objs.each{ |o| yield(o) }
      end
      return ( objs.size >1 ? objs : objs[0] )
    end
    
    # Path argument can be an array of paths
    # or a file (wildcards are allowed)
    # loading from a YAML file
    def from_f( path )

      path = Dir[ path ].sort if path.is_a?( String )

      SOCMaker::logger.warn( "No file(s) found to load" ) if path.size == 0

      yaml_str = ""
      path.each do |file|
        SOCMaker::logger.info "reading:" + file
        yaml_str << File.read( file )
      end
      o = from_s( yaml_str )
      o.dir = File.dirname( path.first )
      return o
    end
    
  end


  
  #
  # small module to extend classes,
  # which need to be written as yaml 
  # output
  module YAML_EXT 

    # we remember always, were we've loaded a yaml file
    attr_accessor :dir

    def save_yaml( args )
      path =  args.size==0 ? @spec_path : args.first
      File.open( path, 'w') {|f| f.write SOCMaker::YPP.from_yaml( YAML.dump( self ) ) } 
    end
  end 


  #
  # This sub-module contains some error-functionallity,
  # which is used in different classes via mixins.
  #
  # serr_if  means  raise Structure ERRor IF ...
  # verr_if  means  raise Value ERRor IF ...
  # lerr_if  means  raise Library ERRor IF ...
  # perr_if  mean   raise Processing ERRor IF
  module ERR
    class YAMLParseError < RuntimeError
    end

    class StructureError < RuntimeError
      attr :name
      attr :field
      def initialize( name, field, message )
        super message
        @name   = name
        @field  = field
       # p message
        SOCMaker::logger.error( "StructureError raised: " + message + " (#{name},#{field})" )
      end
      def to_s
        "->#{@name}:#{@field}"
      end
    end

    class LibError < RuntimeError
      attr :name
      def initialize( requested, message )
        super message
        @name = requested
        SOCMaker::logger.error( "LibError raised: " + message + " (#{requested})" )
      end
      def to_s
        "->#{@name}"
      end
    end

    class ProcessingError < RuntimeError
      def initialize( message )
        super message
        SOCMaker::logger.error( "ProcessingError raised: " + message )
      end
    end

    class ValueError < RuntimeError
      attr :name
      attr :field
      def initialize( name, field, message )
        super message
        @name = name
        @field = field
        SOCMaker::logger.error( "ValueError raised: " + message + " (#{name},#{field})" )
      end
      def to_s
        "->#{@name}:#{@field}"
      end
    end



    def serr_if( res, msg, o={} )
      o = { instance: '??', field: '??' }.merge( o )
      if !!( res )
        raise  StructureError.new( o[:instance], o[:field], msg ) 
      end
    end
 
    def verr_if( res, msg, o={})
      o = { instance: '??', field: '??' }.merge( o )
      if !!( res )
        raise ValueError.new( o[:instance], o[:field], msg )
      end
    end
 
    def lerr_if( res, msg, o={})
      o = { requested: '??' }.merge( o )
      if !!( res )
        raise LibError.new( o[:requested], msg )
      end
    end
 
    def perr_if( res, msg )
      if !!( res )
        raise ProcessingError.new( msg )
      end
    end

  end # module ERR




  # :stopdoc:
  LIBPATH = ::File.expand_path('..', __FILE__) + ::File::SEPARATOR
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
  VERSION = ::File.read(PATH + 'version.txt').strip
  # :startdoc:

  # Returns the library path for the module. If any arguments are given,
  # they will be joined to the end of the libray path using
  # <tt>File.join</tt>.
  #
  def self.libpath( *args )
    rv =  args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
    if block_given?
      begin
        $LOAD_PATH.unshift LIBPATH
        rv = yield
      ensure
        $LOAD_PATH.shift
      end
    end
    return rv
  end

  # Returns the lpath for the module. If any arguments are given,
  # they will be joined to the end of the path using
  # <tt>File.join</tt>.
  #
  def self.path( *args )
    rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
    if block_given?
      begin
        $LOAD_PATH.unshift PATH
        rv = yield
      ensure
        $LOAD_PATH.shift
      end
    end
    return rv
  end

  def self.require_all_libs
    file  = ::File.basename(__FILE__, '.*')
    dir = ::File.dirname(__FILE__)
    %w[ ypp         lib_inc   
        component
        core_def    core_inst 
        hdl_file    ifc_def
        ifc_port    ifc_spc
        soc_def     parameter 
        sparameter  hdl_coder
        lib  cli conf].each { |rb| require ::File.expand_path(
                  ::File.join( dir, file, rb ) )  }
  end

end  # module SOCMaker

SOCMaker.require_all_libs

# vim: noai:ts=2:sw=2

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.