mkexec 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/perl
  2. # make an executable file
  3. use strict;
  4. use warnings;
  5. sub usage; sub mkexec; sub guesstype; sub getcmd; sub launch_editor;
  6. my $DEFAULT_TYPE = 'sh';
  7. my $DEFAULT_MODE = 0755;
  8. my $DEFAULT_FORCE = 0;
  9. ## .... ## . . . . . . . . . . .
  10. ## INIT ## -------------------------------------------------------------------
  11. ## '''' ## ' ' ' ' ' ' ' ' ' ' '
  12. my $force = $DEFAULT_FORCE;
  13. my $name; my $type;
  14. foreach (@ARGV) {
  15. if (m/-f|--force/) {
  16. $force++;
  17. } elsif (defined $name) {
  18. $type = $_;
  19. } else {
  20. $name = $_;
  21. }
  22. }
  23. usage unless defined $name;
  24. $type = guesstype $name unless defined $type;
  25. my $bangs = {
  26. pl => `which perl`,
  27. sh => '/bin/sh',
  28. py => `which python`,
  29. bash => '/bin/bash',
  30. sed => `which sed`,
  31. bc => `which bc`
  32. };
  33. my $templates = {
  34. pl => "use strict;\nuse warnings;\n",
  35. py => "if __name__ == '__main__':\n"
  36. };
  37. my $editors = [ qw/ vim editor / ];
  38. my $cmds;
  39. $cmds->{vim}->{test} = "vim --version 2>/dev/null";
  40. $cmds->{vim}->{run} = "vim +\"normal G\$\" '%s'";
  41. $cmds->{editor}->{test} = "editor --version 2>/dev/null";
  42. $cmds->{editor}->{run} = "editor '%s'";
  43. ## ... ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  44. ## RUN ## ----------------------------------------------------------------- #
  45. ## ''' ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  46. if (exists $bangs->{$type}) {
  47. $force and -e $name
  48. and (defined `cp "$name" "$name~"` or die $!);
  49. (not -e $name or $force)
  50. and mkexec $name, mkbody($type);
  51. chmod $DEFAULT_MODE, $name;
  52. launch_editor $name;
  53. } else {
  54. die "unknown type: $type\n";
  55. }
  56. ## .... ## ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''-.
  57. ## SUBZ ## ----------------------------------------------------------------- :
  58. ## '''' ## ..............................................................-'
  59. sub usage {
  60. print STDERR "usage: $0 [-f] filename [type]\n";
  61. exit 0;
  62. }
  63. sub guesstype {
  64. my $name = shift;
  65. my ($ext) = $name =~ m|\.(\w+)$|;
  66. return ( $ext ? $ext : $DEFAULT_TYPE);
  67. }
  68. sub mkbody {
  69. my $type = shift;
  70. my $tmpl = "";
  71. $tmpl .= $templates->{$type} if exists $templates->{$type};
  72. return sprintf "#!%s\n%s\n", $bangs->{$type}, $tmpl;
  73. }
  74. sub mkexec {
  75. my ($name, $body) = @_;
  76. open EXE, ">", $name or die "cannot open $name for writing: $!\n";
  77. -W EXE or die "file $name is not writable\n";
  78. print EXE $body;
  79. close EXE or die "cannot close $name: $!\n";
  80. }
  81. sub get_cmd {
  82. foreach (@$editors) {
  83. return $cmds->{$_}->{run} if `$cmds->{$_}->{test}`
  84. }
  85. warn "no supported editor available\n";
  86. return;
  87. }
  88. sub launch_editor {
  89. my $name = shift;
  90. my $form = get_cmd;
  91. if ($form) {
  92. my $command = sprintf get_cmd, $name;
  93. exec "$command";
  94. } else { return }
  95. warn "failed to launch editor: $form\n";
  96. }