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