X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=reprap-play.git;a=blobdiff_plain;f=commitid.scad.pl;h=48585d5fd11909e402306a99ede5870aa166545c;hp=e1caf36d28b3858d8228713f5a0ab3878f24c59b;hb=0bd64b9ae61ec61a944e56c6d15e7466720d837d;hpb=5c7ecbf56066a938bdb4635ef274af12d8ca788b diff --git a/commitid.scad.pl b/commitid.scad.pl index e1caf36..48585d5 100755 --- a/commitid.scad.pl +++ b/commitid.scad.pl @@ -3,40 +3,194 @@ use strict; $SIG{__WARN__} = sub { die @_; }; +# xxx much of the comment below is TODO +# +# Usage: +# +# .../commitid.scad.pl [OPTION...] [STRING...] >commitid.scad.new \ +# && mv -f commitid.scad.new commitid.scad +# +# Options: +# +# --git generate git commit indications, as shown below +# (this is the default if no strings are requested with -t) +# +# --git=object +# generate git commit indication based on commit object only +# (ie avoid counting commits) +# +# -i do not generate `+' if git-untracked files are present +# +# [-t[FORM]] TEXT +# generate a form FORM containing TEXT +# TEXT can contain newlines (final newline usually undesirable) +# if FORM not specified, generates Arg0 Arg1 Arg2 in sequence +# character set is SPC 0-9 a-f + * +# # We generate a physical indication of which commit was used. # -# We can generate three forms: +# We provide for scaling factors with dynamic variables: +# $Commitid_pixelsz if not set, we use 0.8 } multiplied +# $Commitid_scale if not set, we use 1.0 } together +# $Commitid_depth if not set, we use xy pixel size from above / 2 +# $Commitid_depth_scale if not set, we use 1.0 (multiplies depth above) +# +# For each form we have +# +# module Commitid_Form_2D() { ... } +# module Commitid_Form() { ... } +# function Commitid_Form_sz() => [ x, y ] +# +# These have their origin in the bottom left corner. The 3D model +# is a positive, has its origin halfway through, and is twice the +# depth in height, so it can be added or subtracted. # -# Tiny3: -# Tiny4: -# Tiny5: -# Tiny6: -# Tiny7: -# Tiny8: +# And we provide +# +# function Commitid_pixelsz() // $Commitid_pixelsz * $Commitid_scale +# function Commitid_depth() // see above +# +# We can generate these forms: +# +# Small3: +# Small4: +# Small5: +# Small6: +# Small7: +# Small8: +# Small9: +# Small10: # git rev-list --first-parent --count HEAD # typically 3-4 characters but we allow for up to 6 +# padded with zeroes; if too long we reduce mod 10^n +# eg +# Small4 1070 +# If tree is dirty, + or * is suffixed, reducing number of +# digits by 1. +# +# Small4S: +# Small6S: Small6T: +# Small8S: Small9T: +# Small10S: +# same but split into two lines (S) or three lines (T) eg +# Small4S 10 Small6t 1 +# 70 07 +# 0* +# +# Git4 Git4S +# Git6 Git6S Git6T +# Git8 Git8S +# Git9 Git9T +# Git10 Git10S +# git-rev-parse HEAD (prefix of requested length) # eg -# Tiny4 1070 -# -# Tiny4Q: -# Tiny6Q: -# Tiny9Q: -# same but in two lines eg -# Tiny4Q 10 -# 70 -# -# Small4 -# Small6 -# Small8 +# Git6 82f2a2 +# If tree is dirty, + or * is suffixed to commitid, +# reducing number of hex digits by 1. + +# Full3 +# Full4 +# Full5 +# Full6 +# Full7 +# Full8 +# Full9 +# Full10 # git-rev-list --first-parent --count HEAD # git-rev-parse HEAD # eg -# Small6 1070 +# Full6 1070 # 82f2a2 +# If tree is dirty, + or * is suffixed to count (but not to +# commitid) reducing number of digits by 1. +# +# Full6T +# Full9T +# Full12T +# Full15T +# As Full but commit is split over two lines for a 3-line message +# +# FontDemo +# +# Arg0, Arg1, ... +# Strings passed on command line + +sub p { print @_ or die $!; } + +p <<'END'; +// *** AUTOGENERATED - DO NOT EDIT *** // +function Commitid_pixelsz() = + ($Commitid_pixelsz ? $Commitid_pixelsz : 0.8) * + ($Commitid_scale ? $Commitid_scale : 1.0); +function Commitid_depth() = + ($Commitid_depth ? $Commitid_depth : Commitid_pixelsz()/2) * + ($Commitid_depth_scale ? $Commitid_depth_scale : 1.0); +function Commitid__scale() = + Commitid_pixelsz() / 0.2; +END + +sub chrmodname ($) { + my ($chr) = @_; + my $chrx = sprintf '%#x', ord $chr; + return "Commitid__chr_$chrx"; +} + +our $gtm_demo_i = -1; +our $gtm_demo_j; +our @gtm_demo_o; + +sub gentextmodule_demo_start_batch ($;$) { + ($gtm_demo_i, $gtm_demo_j) = @_; + $gtm_demo_j //= 0; +} + +sub gentextmodule ($@) { + my ($form, @lines) = @_; + my $modb = "Commitid_$form"; + p "module ${modb}_2D(){\n"; + p " // |$_|\n" foreach @lines; + p " scale(Commitid__scale()){\n"; + my $y = @lines; + my $cols = 1; + foreach my $line (@lines) { + $y--; + my $x = 0; + foreach my $chr (split //, $line) { + p sprintf " translate([%d * 0.8, %d * 1.2]) %s();\n", + $x, $y, chrmodname $chr + if $chr =~ m/\S/; + $x++; + } + $cols = $x if $x > $cols; + } + p " }\n"; + p "}\n"; + p "module ${modb}(){\n"; + p " d=Commitid_depth();\n"; + p " translate([0,0,-d]) linear_extrude(height=d*2) ${modb}_2D();\n"; + p "}\n"; + + p sprintf "function %s_sz() = Commitid__scale() * 0.1 * [ %d, %d ];\n", + $modb, 2 * ($cols * 4 - 1), 2 * (@lines * 6 - 1); + + push @gtm_demo_o, <) { + for (;;) { + $_ = // die; last if %cellmap && !m/\S/; next unless m/\S/; chomp; @@ -46,18 +200,20 @@ sub parsefont () { my %chrpolys; while () { next unless m/\S/; + chomp; my @chrs = split / /, $_; !~ m/\S/ or die; - foreach my $row (0..4) { + foreach my $row (reverse 0..4) { $_ = ; chomp; s{^}{ }; - $_ .= ' ' x (@chrs * 4); + $_ .= ' ' x 8; m{\S/\S} and die; s{/(?=\s)}{L}g; s{/(?=\S)}{r}g; s{\\(?=\s)}{l}g; s{\\(?=\S)}{R}g; + p "// $_\n"; foreach my $chr (@chrs) { s{^ }{} or die "$chr $_ ?"; foreach my $col (0..2) { @@ -66,8 +222,8 @@ sub parsefont () { } elsif (s{^\S}{}) { my $f = $cellmap{$&}; die unless $f; - $f =~ s/\b\d/ sprintf '%x', $col*2 + $& /ge; - $f =~ s/\d\b/ sprintf '%x', $row*2 + $& /ge; + $f =~ s/\b\d/ sprintf '%05d', $col*2000 + $&*1025 /ge; + $f =~ s/\d\b/ sprintf '%05d', $row*2000 + $&*1025 /ge; push @{ $chrpolys{$chr} }, [ split / /, $f ]; } else { die "$_ ?"; @@ -77,45 +233,189 @@ sub parsefont () { die "$_ ?" if m{\S}; } } - foreach my $polys (values %chrpolys) { - my %edges; - foreach my $p (@$polys) { - foreach my $ei (0..$#$p) { - my $e = $p->[$ei].$p->[($ei+1) % @$p]; - die if $edges{$e}; - $edges{$e} = [ $p, $ei ]; + + my $demo = ''; + my $democols = 6; + foreach my $chr (sort keys %chrpolys) { + my $mod = chrmodname $chr; + p "module $mod () {\n"; + foreach my $poly (@{ $chrpolys{$chr} }) { + p " polygon(["; + my $delim = ""; + foreach my $pt (@$poly) { + p $delim; + $pt =~ s{\d{5}}{$&,}; + $pt =~ s{\b\d}{$&.}g; + p "[$pt]"; + $delim = ','; } + p "]);\n"; } - AGAIN: { - foreach my $pa (@$polys) { - foreach my $eai (0..$#$pa) { - my $ear = $pa->[ ($eai+1) % @$pa ].$pa->[$eai]; - my $ebi = $edges{$ear}; - next unless $ebi; - my $pb; - ($pb, $ebi) = @$ebi; -# print "# merging $eai $ebi\n"; - splice @$pb, $ebi, 1; - splice @$pa, $eai, 1, @$pb; - @$pb = ( ); - next AGAIN; - } + p "}\n"; + $demo .= $chr; + } + @demo = reverse $demo =~ m{.{1,$democols}}go; +} + +parsefont(); + +our $do_git; # contains may chars 'c' (count) and/or 'o' (object) +our $do_git_untracked = 1; +our $argcounter; + +sub rjustt ($$) { # right justify and truncate (ie, pad and truncate at left) + my ($sz, $whole) = @_; + my $lw = length $whole; + return $lw > $sz + ? substr($whole, $lw-$sz) + : sprintf "%${sz}s", $whole; +} + +sub ljustt ($$$) { # always includes $suffix + my ($sz, $whole, $suffix) = @_; + $sz -= length $suffix; + return sprintf "%-${sz}.${sz}s%s", $whole, $suffix; +} + +sub gentextmodule_q ($$$) { + my ($form, $s, $lines) = @_; + $gtm_demo_j++; + my $l = length $s; + return if $l % $lines; + my $e = $l/$lines; + return if $e < 2; + $gtm_demo_j--; + gentextmodule($form, $s =~ m/.{$e}/g); +} + +sub gentextmodule_plusq ($$) { + my ($form, $s) = @_; + gentextmodule($form, $s); + gentextmodule_q("${form}S", $s, 2); + gentextmodule_q("${form}T", $s, 3); +} + +our @gcmd; + +sub gitrun_start () { + open F, "-|", @gcmd or die "$gcmd[0]: start: $!"; +} + +sub gitrun_done (;$) { + my ($errok) = @_; + $?=0; $!=0; + return if close F; + return if $errok; + die $! if $!; + die "@gcmd failed ($?)\n"; +} + +sub gitoutput (@) { + (@gcmd) = (qw(git), @_); + gitrun_start; + $_ = ; + gitrun_done; + defined or die "@gcmd produced no output"; + chomp or die "@gcmd produced no final newline"; + $_; +} + +sub do_git () { + return unless $do_git; + + @gcmd = qw(git status --porcelain); + push @gcmd, qw(--untracked=no) unless $do_git_untracked; + + my $git_dirty = ''; + gitrun_start; + while () { + if (m/^\?\?/ && $do_git_untracked) { + $git_dirty = '+'; + next; + } + $git_dirty = '*'; + last; + } + gitrun_done($git_dirty eq '*'); + + my $git_count; + my $git_object; + + if ($do_git =~ m/c/) { + $git_count = gitoutput qw(rev-list --first-parent --count HEAD); + } + if ($do_git =~ m/o/) { + $git_object = gitoutput qw(rev-parse HEAD); + } + + foreach my $sz (3..10) { + gentextmodule_demo_start_batch($sz-3); + + gentextmodule_plusq("Small$sz", rjustt($sz, $git_count.$git_dirty)) + if defined $git_count; + + gentextmodule_plusq("Git$sz", ljustt($sz, $git_object, $git_dirty)) + if defined $git_object; + + if (defined $git_count && defined $git_object) { + gentextmodule("Full$sz", + rjustt($sz, $git_count.$git_dirty), + ljustt($sz, $git_object, '')); + + if (!($sz % 2)) { + my $e = $sz/2; + gentextmodule("Full".($e*3)."T", + rjustt($e, $git_count), + ljustt($e*2, $git_object, $git_dirty) + =~ m/.{$e}/g); } } -# @$polys = grep { @$_ } @$polys; } - - use Data::Dumper; - print Dumper(\%chrpolys); +} + +while (@ARGV) { + $_ = shift; + if (m/^--(no)?-git$/) { + $do_git = $1 ? '' : 'co'; + } elsif (m/^---git=object$/) { + $do_git = 'o'; + } elsif (m/^-i$/) { + $do_git_untracked = 0; + } elsif (m/^-t(.*)$/) { + my $form = $1; + die "bad usage: -t needs string argument\n"; + $_ = shift; + gentextmodule($form, split /\n/, $_); + $argcounter //= 0; + } elsif (m/^[^-]/) { + gentextmodule("Arg$argcounter", $_); + $argcounter++; + } else { + die "bad usage: unknown option \`$_'\n"; + } } -parsefont(); +$do_git //= defined($argcounter) ? '' : 'co'; + +gentextmodule_demo_start_batch(-1); +gentextmodule('FontDemo', @demo); + +do_git(); + +p "module Commitid_2DDemo(){\n"; +p " st = Commitid__scale() * [ 10, 5 ];\n"; +p " e = Commitid_pixelsz();\n"; +p $_ foreach @gtm_demo_o; +p "}\n"; + +flush STDOUT or die $!; +close STDOUT or die $!; __DATA__ # 00 20 22 02 -l 00 20 22 -r 00 20 02 +l 00 20 02 +r 00 20 22 L 00 22 02 R 20 22 02 > 00 20 22 02 11 @@ -123,17 +423,24 @@ R 20 22 02 0 1 2 3 4 5 6 7 8 9 -/#\ # ##\ ##\ # # ### /## ### /#\ /#\ -# # # # # # # # # # # # # # -# # # /#/ ### ### ##\ ##\ // >#< \## +/#\ r /#\ ##\ # # ### // ### /#\ /#\ +# # /# # # # # # # # # # # # +# # # /#/ ##< \## ##\ ##\ // >#< \## # # # # # # # # # # # # # -\#/ # ### ##/ # ##/ \#/ # \#/ ##/ +\#/ /#\ ### ##/ # ##/ \#/ # \#/ ##/ a b c d e f # # /## -/## ##\ /## /## /## # -# # # # # # # # # ### + # /## # /#\ # +/## ##\ # /## #r# ### # # # # # # # #/ # -\## ##/ \## \## ### # +\## ##/ \## \## \#/ # + ++ * + # # + # \#/ +### ### + # /#\ + # #