| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  | /* Tool to sort attribute sets.  Primarily useful for keeping | 
					
						
							|  |  |  |    all-packages.nix tidy. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    To compile: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    $ strc -i ../../maintainers/scripts/sort-attrs.str -la stratego-lib | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Typical invocation: | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |    $ sglr -m -p ~/Dev/nix/src/libexpr/nix.tbl -i all-packages.nix \ | 
					
						
							|  |  |  |      | implode-asfix --lex \ | 
					
						
							|  |  |  |      | ../../maintainers/scripts/sort-attrs \ | 
					
						
							|  |  |  |      | asfix-yield | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  |       | 
					
						
							|  |  |  | module sort-attrs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | imports | 
					
						
							|  |  |  |   libstratego-lib | 
					
						
							|  |  |  |   libstratego-sglr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | strategies | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   no-wsp = !appl(prod([], cf(opt(layout())), no-attrs()), []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  | rules | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  |   list-sep(s): [] -> [] | 
					
						
							|  |  |  |   list-sep(s): [x | xs] -> [[x | before] | <list-sep(s)> [split | after]] | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <split-fetch-keep(s)> xs => (before, split, after) | 
					
						
							|  |  |  |   list-sep(s): [x | xs] -> [[x | xs]] | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <not(split-fetch-keep(s))> xs | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |   list-sep-end(s): xs -> [<conc> (before, [split]) | <list-sep-end(s)> after] | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <split-fetch-keep(s)> xs => (before, split, after) | 
					
						
							|  |  |  |   list-sep-end(s): xs -> [xs] | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <not(split-fetch-keep(s))> xs | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  |    | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  |   sort-attrs: | 
					
						
							|  |  |  |     appl(p@prod(_, _, attrs([term(cons("Attrs"))])), | 
					
						
							|  |  |  |       [ lit("{") | 
					
						
							|  |  |  |       , ws1 | 
					
						
							|  |  |  |       , appl(p2@list(cf(iter-star(sort("Bind")))), attrs) | 
					
						
							|  |  |  |       , ws2 | 
					
						
							|  |  |  |       , lit("}") | 
					
						
							|  |  |  |       ] | 
					
						
							|  |  |  |     ) -> | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  |     appl(p, [lit("{"), <no-wsp>, appl(p2, <concat> attrs'), ws2, lit("}")]) | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  |     where | 
					
						
							|  |  |  |       <debug> "found it"; | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  |       <attach-wsp> [ws1 | attrs] => withWSP; | 
					
						
							|  |  |  |       <list-sep(starts-section)> withWSP => groups; | 
					
						
							|  |  |  |       <length; debug> groups; | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |       <map({x', x'', x''', xs', starts, starts': \[x | xs] -> [x''' | xs'] | 
					
						
							|  |  |  |         where | 
					
						
							|  |  |  |           <remove-section-start> x => (x', starts); | 
					
						
							| 
									
										
										
										
											2006-10-18 14:04:41 +00:00
										 |  |  |           <map(regularise-empty-lines); if !starts; debug; sortable-section; debug then qsort(compare-attrs) else id end> [x' | xs] => [x'' | xs']; | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |           <[] <+ \x -> ["\n\n\n" | x]\ > starts => starts'; | 
					
						
							| 
									
										
										
										
											2006-09-15 15:14:50 +00:00
										 |  |  |           <prepend-layout> (starts', x'') => x''' | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |       \ })> groups => attrs'; | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  |       <debug> "did it" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  |   attach-wsp: [a, b | cs] -> [(a, b) | <attach-wsp> cs] | 
					
						
							|  |  |  |   attach-wsp: [] -> [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  | strategies | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   starts-section = | 
					
						
							|  |  |  |     ?x@(appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr); | 
					
						
							|  |  |  |     <implode-string; is-substring(!"###")> cs; | 
					
						
							|  |  |  |     !x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | rules | 
					
						
							| 
									
										
										
										
											2006-10-18 14:04:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2006-10-18 14:04:41 +00:00
										 |  |  |   sortable-section = ?[s]; !s; explode-string; not(fetch({x: ?x; !(x, 97); geq})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |   remove-section-start: | 
					
						
							|  |  |  |     (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) -> | 
					
						
							|  |  |  |     ((appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs'), attr), starts) | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       !cs; | 
					
						
							|  |  |  |       list-sep-end(?10); // separate into lines, keeping the \n | 
					
						
							|  |  |  |       map(implode-string); | 
					
						
							|  |  |  |       partition(where(is-substring(!"###"))) => (starts, rest); | 
					
						
							|  |  |  |       <map(explode-string); concat> rest => cs' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   regularise-empty-lines: | 
					
						
							|  |  |  |     (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr) -> | 
					
						
							|  |  |  |     (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr) | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       // separate into lines, keeping the \n | 
					
						
							|  |  |  |       // last whitespace is significant, keep | 
					
						
							|  |  |  |       <list-sep-end(?10); split-init-last> cs => (init, last); | 
					
						
							| 
									
										
										
										
											2006-09-15 15:14:50 +00:00
										 |  |  |       <regularise-empty-lines'> init => cs'; // remove whitespace-only lines | 
					
						
							|  |  |  |       <concat> [<explode-string> "\n\n", <concat> cs', last] => cs'' // add one empty line | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |   /* Dirty hack: *do* keep the first empty line following a non-empty line. !!! order matters */ | 
					
						
							|  |  |  |   regularise-empty-lines': [] -> [] | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |   regularise-empty-lines': [x, y | xs] -> [x, y | <regularise-empty-lines'> xs] | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <fetch-elem(not(?10 <+ ?32))> x; | 
					
						
							|  |  |  |       <not(fetch-elem(not(?10 <+ ?32)))> y | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |   regularise-empty-lines': [x | xs] -> [x | <regularise-empty-lines'> xs] | 
					
						
							|  |  |  |     where <fetch-elem(not(?10 <+ ?32))> x | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |   regularise-empty-lines': [x | xs] -> <regularise-empty-lines'> xs | 
					
						
							|  |  |  |     where <not(fetch-elem(not(?10 <+ ?32)))> x | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |        | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   prepend-layout: | 
					
						
							|  |  |  |     (text, (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs), attr)) -> | 
					
						
							|  |  |  |     (appl(prod([cf(layout())], cf(opt(layout())), no-attrs()), cs''), attr) | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <implode-string> cs => cs'; | 
					
						
							|  |  |  |       <conc-strings; explode-string> (<concat-strings> text, cs') => cs'' | 
					
						
							| 
									
										
										
										
											2006-09-11 16:18:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   compare-attrs: | 
					
						
							|  |  |  |     x@ | 
					
						
							|  |  |  |     ( (_, appl(p1@prod(_, _, attrs([term(cons("Bind"))])), [id1 | xs1])) | 
					
						
							|  |  |  |     , (_, appl(p2@prod(_, _, attrs([term(cons("Bind"))])), [id2 | xs2])) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     -> x | 
					
						
							|  |  |  |     where | 
					
						
							|  |  |  |       <string-lt> (id1, id2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | strategies | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   main = io-wrap( | 
					
						
							| 
									
										
										
										
											2006-09-15 14:40:11 +00:00
										 |  |  |     oncetd(sort-attrs) | 
					
						
							| 
									
										
										
										
											2006-09-11 14:33:32 +00:00
										 |  |  |   ) |