github.com/hwaf/hwaf@v0.0.0-20140814122253-5465f73b20f1/hlib/hrender.go (about)

     1  package hlib
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  	"text/template"
    10  )
    11  
    12  type HscriptYmlEncoder struct {
    13  	w io.Writer
    14  }
    15  
    16  func NewHscriptYmlEncoder(w io.Writer) *HscriptYmlEncoder {
    17  	return &HscriptYmlEncoder{w: w}
    18  }
    19  
    20  func (enc *HscriptYmlEncoder) Encode(wscript *Wscript_t) error {
    21  	var err error
    22  
    23  	// generate package header ------------------------------------------------
    24  	const pkg_hdr_tmpl = `
    25  ## package header
    26  package: {
    27      name:    {{.Name}},
    28      authors: {{.Authors | as_hlist}},
    29  {{if .Managers}}    managers: {{.Managers | as_hlist}},{{end}}
    30  {{if .Version}}    version:  "{{.Version}}",{{end}}
    31      deps: {
    32  {{. | gen_hscript_pkg_deps}}
    33      }
    34  }
    35  `
    36  	err = h_tmpl(enc.w, pkg_hdr_tmpl, wscript.Package)
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	// generate options - section ---------------------------------------------
    42  	err = h_tmpl(
    43  		enc.w,
    44  		`
    45  options: {
    46      tools: [{{range .Tools}}{{.}}{{end}}],
    47  }
    48  `,
    49  		wscript.Options,
    50  	)
    51  	if err != nil {
    52  		return err
    53  	}
    54  
    55  	// generate configure - section -------------------------------------------
    56  	err = h_tmpl(
    57  		enc.w,
    58  		`
    59  configure: {
    60      tools: [{{range .Tools}}{{.}}{{end}}],
    61      env: {
    62  {{.Stmts | gen_hscript_env}}
    63      },
    64      alias: {
    65  {{.Stmts | gen_hscript_aliases}}
    66      },
    67  }
    68  `,
    69  		wscript.Configure,
    70  	)
    71  	if err != nil {
    72  		return err
    73  	}
    74  
    75  	// generate build - section -----------------------------------------------
    76  	err = h_tmpl(
    77  		enc.w,
    78  		`
    79  build: {
    80  {{with .Targets}}{{. | gen_hscript_targets}}{{end}}
    81  }
    82  `,
    83  		wscript.Build,
    84  	)
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	_, err = fmt.Fprintf(
    90  		enc.w,
    91  		"\n## EOF ##\n",
    92  	)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	return err
    98  }
    99  
   100  func h_tmpl(w io.Writer, text string, data interface{}) error {
   101  	t := template.New("hscript")
   102  	t.Funcs(template.FuncMap{
   103  		"trim": strings.TrimSpace,
   104  		"as_hlist": func(alist interface{}) string {
   105  			rv := reflect.ValueOf(alist)
   106  			str := make([]string, 0, rv.Len())
   107  			for i := 0; i < rv.Len(); i++ {
   108  				s := rv.Index(i)
   109  				str = append(str, fmt.Sprintf("%s", s))
   110  			}
   111  			return "[" + strings.Join(str, ", ") + "]"
   112  		},
   113  		"gen_hscript_pkg_deps": gen_hscript_pkg_deps,
   114  		"gen_hscript_env":      gen_hscript_env,
   115  		"gen_hscript_aliases":  gen_hscript_aliases,
   116  		"gen_hscript_targets":  gen_hscript_targets,
   117  	})
   118  	template.Must(t.Parse(text))
   119  	return t.Execute(w, data)
   120  }
   121  
   122  func gen_hscript_pkg_deps(pkg Package_t) string {
   123  	const indent = "    "
   124  	var str []string
   125  	public_deps := make([]Dep_t, 0, len(pkg.Deps))
   126  	private_deps := make([]Dep_t, 0, len(pkg.Deps))
   127  	runtime_deps := make([]Dep_t, 0, len(pkg.Deps))
   128  
   129  	for _, dep := range pkg.Deps {
   130  		if dep.Type.HasMask(RuntimeDep) {
   131  			runtime_deps = append(runtime_deps, dep)
   132  		}
   133  		if dep.Type.HasMask(PublicDep) {
   134  			public_deps = append(public_deps, dep)
   135  		}
   136  		if dep.Type.HasMask(PrivateDep) {
   137  			private_deps = append(private_deps, dep)
   138  		}
   139  	}
   140  
   141  	if len(public_deps) > 0 {
   142  		str = append(str, "public: [")
   143  		for _, dep := range public_deps {
   144  			str = append(str, fmt.Sprintf("%s%s,", indent, dep.Name))
   145  		}
   146  		str = append(str, "],")
   147  	} else {
   148  		str = append(str, "public: [],")
   149  	}
   150  
   151  	if len(private_deps) > 0 {
   152  		str = append(str, "private: [")
   153  		for _, dep := range private_deps {
   154  			str = append(str, fmt.Sprintf("%s%s,", indent, dep.Name))
   155  		}
   156  		str = append(str, "],")
   157  	} else {
   158  		str = append(str, "private: [],")
   159  	}
   160  
   161  	if len(runtime_deps) > 0 {
   162  		str = append(str, "runtime: [")
   163  		for _, dep := range runtime_deps {
   164  			str = append(str, fmt.Sprintf("%s%s,", indent, dep.Name))
   165  		}
   166  		str = append(str, "],")
   167  	} else {
   168  		str = append(str, "runtime: [],")
   169  	}
   170  
   171  	// reindent:
   172  	for i, s := range str {
   173  		str[i] = indent + indent + s
   174  	}
   175  
   176  	return strings.Join(str, "\n")
   177  }
   178  
   179  func gen_hscript_env(stmts []Stmt) string {
   180  	const indent = "    "
   181  	var str []string
   182  
   183  	for _, stmt := range stmts {
   184  		switch stmt := stmt.(type) {
   185  		case *MacroStmt:
   186  			str = append(str,
   187  				h_py_hlib_value(indent, stmt.Value)...,
   188  			)
   189  		}
   190  	}
   191  	// reindent:
   192  	for i, s := range str {
   193  		str[i] = indent + indent + s
   194  	}
   195  
   196  	return strings.Join(str, "\n")
   197  }
   198  
   199  func gen_hscript_aliases(stmts []Stmt) string {
   200  	const indent = "    "
   201  	var str []string
   202  
   203  	for _, stmt := range stmts {
   204  		switch stmt := stmt.(type) {
   205  		case *AliasStmt:
   206  			str = append(str,
   207  				h_py_hlib_value(indent, stmt.Value)...,
   208  			)
   209  		}
   210  	}
   211  	// reindent:
   212  	for i, s := range str {
   213  		str[i] = indent + indent + s
   214  	}
   215  
   216  	return strings.Join(str, "\n")
   217  }
   218  
   219  func gen_hscript_targets(tgts Targets_t) string {
   220  	const indent = "    "
   221  	var str []string
   222  
   223  	cnv_values := func(values []Value) []string {
   224  		out := make([]string, 0, len(values))
   225  		for _, v := range values {
   226  			// FIXME what about the non-default values ??
   227  			out = append(out, v.Set[0].Value...)
   228  		}
   229  		return out
   230  	}
   231  
   232  	for _, tgt := range tgts {
   233  		str = append(str, "")
   234  		str = append(str, fmt.Sprintf("%s: {", tgt.Name))
   235  		srcs := cnv_values(tgt.Source)
   236  		str = append(str,
   237  			fmt.Sprintf("%sfeatures: %q,", indent, strings.Join(tgt.Features, " ")),
   238  			fmt.Sprintf("%ssource:   [%s],", indent, w_py_strlist(srcs)),
   239  		)
   240  
   241  		if tgt.Group != "" {
   242  			str = append(
   243  				str,
   244  				fmt.Sprintf("%sgroup:    %q,", indent, tgt.Group),
   245  			)
   246  		}
   247  
   248  		for _, vv := range []struct {
   249  			hdr    string
   250  			values []Value
   251  		}{
   252  			{"use", tgt.Use},
   253  			{"defines", tgt.Defines},
   254  			{"cflags", tgt.CFlags},
   255  			{"cxxflags", tgt.CxxFlags},
   256  			{"linkflags", tgt.LinkFlags},
   257  			{"shlibflags", tgt.ShlibFlags},
   258  			{"stlibflags", tgt.StlibFlags},
   259  			{"rpath", tgt.RPath},
   260  			{"includes", tgt.Includes},
   261  			{"export_includes", tgt.ExportIncludes},
   262  		} {
   263  			if len(vv.values) > 0 {
   264  				vals := cnv_values(vv.values)
   265  				str = append(str,
   266  					fmt.Sprintf(
   267  						"%s%s: [%s],",
   268  						indent,
   269  						vv.hdr,
   270  						w_py_strlist(vals),
   271  					),
   272  				)
   273  			}
   274  		}
   275  
   276  		if len(tgt.Env) > 0 {
   277  			str = append(str,
   278  				fmt.Sprintf("%senv: {", indent),
   279  			)
   280  			for hdr, value := range tgt.Env {
   281  				vals := cnv_values([]Value{value})
   282  				str = append(str,
   283  					fmt.Sprintf(
   284  						"%s%s: [%s],",
   285  						indent+indent,
   286  						hdr,
   287  						w_py_strlist(vals),
   288  					),
   289  				)
   290  			}
   291  			str = append(str,
   292  				indent+"},",
   293  			)
   294  		}
   295  
   296  		for hdr, values := range tgt.KwArgs {
   297  			if len(values) > 0 {
   298  				vals := cnv_values(values)
   299  				str = append(str,
   300  					fmt.Sprintf(
   301  						"%s%s: [%s],",
   302  						indent,
   303  						hdr,
   304  						w_py_strlist(vals),
   305  					),
   306  				)
   307  			}
   308  
   309  		}
   310  		str = append(str,
   311  			"},",
   312  		)
   313  
   314  	}
   315  
   316  	str = append(str, "")
   317  	str = append(str, "hwaf-call: [],")
   318  	// reindent:
   319  	for i, s := range str {
   320  		str[i] = indent + s
   321  	}
   322  
   323  	return strings.Join(str, "\n")
   324  }
   325  
   326  func h_py_hlib_value(indent string, x Value) []string {
   327  	str := make([]string, 0)
   328  
   329  	values := make([][2]string, 0, len(x.Set))
   330  	for _, v := range x.Set {
   331  		k := v.Tag
   332  		values = append(values, [2]string{k, w_py_strlist(v.Value)})
   333  	}
   334  	if len(x.Set) > 1 {
   335  		str = append(
   336  			str,
   337  			fmt.Sprintf(
   338  				"%s: %s,",
   339  				x.Name,
   340  				h_gen_valdict_switch_str(indent, values),
   341  			),
   342  		)
   343  	} else {
   344  		vv := fmt.Sprintf("%s", values[0][1])
   345  		vv, _ = strconv.Unquote(vv)
   346  		v_fmt := "%s: %q,"
   347  		// if values[0][1] == "" {
   348  		// 	v_fmt = "%s: %q,"
   349  		// }
   350  		str = append(
   351  			str,
   352  			fmt.Sprintf(
   353  				v_fmt,
   354  				x.Name,
   355  				vv,
   356  			),
   357  		)
   358  	}
   359  	return str
   360  }
   361  
   362  func h_gen_valdict_switch_str(indent string, values [][2]string) string {
   363  	o := make([]string, 0, len(values))
   364  	o = append(o, "[")
   365  	for _, v := range values {
   366  		tags := w_gen_taglist(v[0])
   367  		key_fmt := "(%s)"
   368  		if strings.Count(v[0], "&") <= 0 {
   369  			key_fmt = "%s"
   370  		}
   371  		val_fmt := "%s"
   372  		if strings.Count(v[1], ",") > 0 {
   373  			val_fmt = "[%s]"
   374  		}
   375  		if len(v[1]) == 0 {
   376  			val_fmt = "%q"
   377  		}
   378  
   379  		o = append(o,
   380  			fmt.Sprintf(
   381  				"%s  {%s: %s},",
   382  				indent,
   383  				fmt.Sprintf(key_fmt, w_py_strlist(tags)),
   384  				fmt.Sprintf(val_fmt, v[1]),
   385  			),
   386  		)
   387  	}
   388  	o = append(o, indent+"]")
   389  	return strings.Join(o, "\n")
   390  }
   391  
   392  // EOF