Browse Source

Added option --format, which lets you change the output format. Useful to manually parse variables, and to avoid using eval.

naelstrof 10 years ago
parent
commit
5cc203e18a
6 changed files with 144 additions and 33 deletions
  1. 27
    2
      README.md
  2. 24
    2
      cmdline.c
  3. 5
    1
      cmdline.h
  4. 5
    0
      gengetopt.sh
  5. 70
    27
      main.cpp
  6. 13
    1
      options.ggo

+ 27
- 2
README.md View File

36
 You can see my implementation of slop in a screenshooter here:
36
 You can see my implementation of slop in a screenshooter here:
37
 https://gist.github.com/naelstrof/6530959
37
 https://gist.github.com/naelstrof/6530959
38
 
38
 
39
+For those of you who don't want eval to be an integral part of slop (Could be dangerous if I were evil!): You can change the output format and parse it manually like so:
40
+```bash
41
+#!/bin/bash
42
+slopoutput=$(slop -f "%x %y %w %h %g $i")
43
+X=$(echo $slopoutput | awk '{print $1}')
44
+Y=$(echo $slopoutput | awk '{print $2}')
45
+W=$(echo $slopoutput | awk '{print $3}')
46
+H=$(echo $slopoutput | awk '{print $4}')
47
+G=$(echo $slopoutput | awk '{print $5}')
48
+ID=$(echo $slopoutput | awk '{print $6}')
49
+maim -g $G -i $ID
50
+ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+$X,$Y -f alsa -i pulse ~/myfile.webm
51
+```
52
+
39
 ## Lets see some action
53
 ## Lets see some action
40
 Ok. Here's a comparison between 'scrot -s's selection and slop's:
54
 Ok. Here's a comparison between 'scrot -s's selection and slop's:
41
 ![scrotbad](http://farmpolice.com/content/images/2014-10-14-12:08:24.png)
55
 ![scrotbad](http://farmpolice.com/content/images/2014-10-14-12:08:24.png)
67
 help
81
 help
68
 ----
82
 ----
69
 ```text
83
 ```text
70
-slop v3.1.5
84
+slop v3.1.7
71
 
85
 
72
-Copyright (C) 2014 Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors)
86
+Copyright (C) 2014 Dalton Nell, Slop Contributors
87
+(https://github.com/naelstrof/slop/graphs/contributors)
73
 
88
 
74
 Usage: slop [options]
89
 Usage: slop [options]
75
 
90
 
113
                                   highlights it. This is only useful when
128
                                   highlights it. This is only useful when
114
                                   --color is set to a transparent color.
129
                                   --color is set to a transparent color.
115
                                   (default=off)
130
                                   (default=off)
131
+  -f, --format=STRING           Set the output format string. Format specifiers
132
+                                  are %x, %y, %w, %h, %i, %g, and %c.
133
+                                  (default=`X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n')
116
 
134
 
117
 Examples
135
 Examples
118
     $ # Gray, thick, transparent border for maximum visiblity.
136
     $ # Gray, thick, transparent border for maximum visiblity.
126
 
144
 
127
     $ # Classic Windows XP selection.
145
     $ # Classic Windows XP selection.
128
     $ slop -l -c 0.3,0.4,0.6,0.4
146
     $ slop -l -c 0.3,0.4,0.6,0.4
147
+
148
+    $ # Change output format to use safer parsing
149
+    $ slopoutput=$(slop -f "%x %y %w %h")
150
+    $ X=$(echo $slopoutput | awk '{print $1}')
151
+    $ Y=$(echo $slopoutput | awk '{print $2}')
152
+    $ W=$(echo $slopoutput | awk '{print $3}')
153
+    $ H=$(echo $slopoutput | awk '{print $4}')
129
 ```
154
 ```

+ 24
- 2
cmdline.c View File

48
   "      --min=INT                 Set the minimum output of width or height\n                                  values. This is useful to avoid outputting 0.\n                                  Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
48
   "      --min=INT                 Set the minimum output of width or height\n                                  values. This is useful to avoid outputting 0.\n                                  Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
49
   "      --max=INT                 Set the maximum output of width or height\n                                  values. Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
49
   "      --max=INT                 Set the maximum output of width or height\n                                  values. Setting min and max to the same value\n                                  disables drag selections.  (default=`0')",
50
   "  -l, --highlight               Instead of outlining selections, slop\n                                  highlights it. This is only useful when\n                                  --color is set to a transparent color.\n                                  (default=off)",
50
   "  -l, --highlight               Instead of outlining selections, slop\n                                  highlights it. This is only useful when\n                                  --color is set to a transparent color.\n                                  (default=off)",
51
-  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n",
51
+  "  -f, --format=STRING           Set the output format string. Format specifiers\n                                  are %x, %y, %w, %h, %i, %g, and %c.\n                                  (default=`X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n')",
52
+  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n",
52
     0
53
     0
53
 };
54
 };
54
 
55
 
87
   args_info->min_given = 0 ;
88
   args_info->min_given = 0 ;
88
   args_info->max_given = 0 ;
89
   args_info->max_given = 0 ;
89
   args_info->highlight_given = 0 ;
90
   args_info->highlight_given = 0 ;
91
+  args_info->format_given = 0 ;
90
 }
92
 }
91
 
93
 
92
 static
94
 static
112
   args_info->max_arg = 0;
114
   args_info->max_arg = 0;
113
   args_info->max_orig = NULL;
115
   args_info->max_orig = NULL;
114
   args_info->highlight_flag = 0;
116
   args_info->highlight_flag = 0;
117
+  args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
118
+  args_info->format_orig = NULL;
115
   
119
   
116
 }
120
 }
117
 
121
 
133
   args_info->min_help = gengetopt_args_info_help[11] ;
137
   args_info->min_help = gengetopt_args_info_help[11] ;
134
   args_info->max_help = gengetopt_args_info_help[12] ;
138
   args_info->max_help = gengetopt_args_info_help[12] ;
135
   args_info->highlight_help = gengetopt_args_info_help[13] ;
139
   args_info->highlight_help = gengetopt_args_info_help[13] ;
140
+  args_info->format_help = gengetopt_args_info_help[14] ;
136
   
141
   
137
 }
142
 }
138
 
143
 
227
   free_string_field (&(args_info->color_orig));
232
   free_string_field (&(args_info->color_orig));
228
   free_string_field (&(args_info->min_orig));
233
   free_string_field (&(args_info->min_orig));
229
   free_string_field (&(args_info->max_orig));
234
   free_string_field (&(args_info->max_orig));
235
+  free_string_field (&(args_info->format_arg));
236
+  free_string_field (&(args_info->format_orig));
230
   
237
   
231
   
238
   
232
 
239
 
283
     write_into_file(outfile, "max", args_info->max_orig, 0);
290
     write_into_file(outfile, "max", args_info->max_orig, 0);
284
   if (args_info->highlight_given)
291
   if (args_info->highlight_given)
285
     write_into_file(outfile, "highlight", 0, 0 );
292
     write_into_file(outfile, "highlight", 0, 0 );
293
+  if (args_info->format_given)
294
+    write_into_file(outfile, "format", args_info->format_orig, 0);
286
   
295
   
287
 
296
 
288
   i = EXIT_SUCCESS;
297
   i = EXIT_SUCCESS;
550
         { "min",	1, NULL, 0 },
559
         { "min",	1, NULL, 0 },
551
         { "max",	1, NULL, 0 },
560
         { "max",	1, NULL, 0 },
552
         { "highlight",	0, NULL, 'l' },
561
         { "highlight",	0, NULL, 'l' },
562
+        { "format",	1, NULL, 'f' },
553
         { 0,  0, 0, 0 }
563
         { 0,  0, 0, 0 }
554
       };
564
       };
555
 
565
 
556
-      c = getopt_long (argc, argv, "hVb:p:t:g:c:nl", long_options, &option_index);
566
+      c = getopt_long (argc, argv, "hVb:p:t:g:c:nlf:", long_options, &option_index);
557
 
567
 
558
       if (c == -1) break;	/* Exit from `while (1)' loop.  */
568
       if (c == -1) break;	/* Exit from `while (1)' loop.  */
559
 
569
 
649
             goto failure;
659
             goto failure;
650
         
660
         
651
           break;
661
           break;
662
+        case 'f':	/* Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c..  */
663
+        
664
+        
665
+          if (update_arg( (void *)&(args_info->format_arg), 
666
+               &(args_info->format_orig), &(args_info->format_given),
667
+              &(local_args_info.format_given), optarg, 0, "X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n", ARG_STRING,
668
+              check_ambiguity, override, 0, 0,
669
+              "format", 'f',
670
+              additional_error))
671
+            goto failure;
672
+        
673
+          break;
652
 
674
 
653
         case 0:	/* Long option with no short option */
675
         case 0:	/* Long option with no short option */
654
           /* Sets the x display..  */
676
           /* Sets the x display..  */

+ 5
- 1
cmdline.h View File

31
 
31
 
32
 #ifndef CMDLINE_PARSER_VERSION
32
 #ifndef CMDLINE_PARSER_VERSION
33
 /** @brief the program version */
33
 /** @brief the program version */
34
-#define CMDLINE_PARSER_VERSION "v3.1.5"
34
+#define CMDLINE_PARSER_VERSION "v3.1.7"
35
 #endif
35
 #endif
36
 
36
 
37
 /** @brief Where the command line options are stored */
37
 /** @brief Where the command line options are stored */
69
   const char *max_help; /**< @brief Set the maximum output of width or height values. Setting min and max to the same value disables drag selections. help description.  */
69
   const char *max_help; /**< @brief Set the maximum output of width or height values. Setting min and max to the same value disables drag selections. help description.  */
70
   int highlight_flag;	/**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. (default=off).  */
70
   int highlight_flag;	/**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. (default=off).  */
71
   const char *highlight_help; /**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. help description.  */
71
   const char *highlight_help; /**< @brief Instead of outlining selections, slop highlights it. This is only useful when --color is set to a transparent color. help description.  */
72
+  char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
73
+  char * format_orig;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. original value given at command line.  */
74
+  const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
72
   
75
   
73
   unsigned int help_given ;	/**< @brief Whether help was given.  */
76
   unsigned int help_given ;	/**< @brief Whether help was given.  */
74
   unsigned int version_given ;	/**< @brief Whether version was given.  */
77
   unsigned int version_given ;	/**< @brief Whether version was given.  */
83
   unsigned int min_given ;	/**< @brief Whether min was given.  */
86
   unsigned int min_given ;	/**< @brief Whether min was given.  */
84
   unsigned int max_given ;	/**< @brief Whether max was given.  */
87
   unsigned int max_given ;	/**< @brief Whether max was given.  */
85
   unsigned int highlight_given ;	/**< @brief Whether highlight was given.  */
88
   unsigned int highlight_given ;	/**< @brief Whether highlight was given.  */
89
+  unsigned int format_given ;	/**< @brief Whether format was given.  */
86
 
90
 
87
 } ;
91
 } ;
88
 
92
 

+ 5
- 0
gengetopt.sh View File

1
+#!/bin/bash
2
+# This is used because a bug in gengetopt keeps you from putting \n in default string options. All it does is replace REPLACEME with the correct code to make the application work properly.
3
+gengetopt < options.ggo
4
+sed -i '0,/REPLACEME/{s/REPLACEME/X=%x\\\\nY=%y\\\\nW=%w\\\\nH=%h\\\\nG=%g\\\\nID=%i\\\\nCancel=%c\\\\n/}' cmdline.c
5
+sed -i 's/REPLACEME/X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n/' cmdline.c

+ 70
- 27
main.cpp View File

19
  */
19
  */
20
 #include <unistd.h>
20
 #include <unistd.h>
21
 #include <cstdio>
21
 #include <cstdio>
22
+#include <sstream>
22
 #include "x.hpp"
23
 #include "x.hpp"
23
 #include "rectangle.hpp"
24
 #include "rectangle.hpp"
24
 #include "cmdline.h"
25
 #include "cmdline.h"
25
 
26
 
26
-void printSelection( bool cancelled, int x, int y, int w, int h, int window ) {
27
-    printf( "X=%i\n", x );
28
-    printf( "Y=%i\n", y );
29
-    printf( "W=%i\n", w );
30
-    printf( "H=%i\n", h );
31
-    printf( "G=%ix%i", w, h );
32
-    if ( x >= 0 ) {
33
-        printf( "+%i", x );
34
-    } else {
35
-        // Negative is already included
36
-        printf( "%i", x );
37
-    }
38
-    if ( y >= 0 ) {
39
-        printf( "+%i", y );
40
-    } else {
41
-        // Negative is already included
42
-        printf( "%i", y );
27
+int printSelection( std::string format, bool cancelled, int x, int y, int w, int h, int window ) {
28
+    size_t pos = 0;
29
+    while ( ( pos = format.find( "%", pos ) ) != std::string::npos ) {
30
+        if ( pos + 1 > format.size() ) {
31
+            fprintf( stderr, "Format error: %% found at the end of format string.\n", format[ pos + 1 ] );
32
+            return 1;
33
+        }
34
+        std::stringstream foo;
35
+        switch( format[ pos + 1 ] ) {
36
+            case '%':
37
+                format.replace( pos, 2, "%" );
38
+                pos += 1;
39
+                break;
40
+            case 'x':
41
+            case 'X':
42
+                foo << x;
43
+                format.replace( pos, 2, foo.str() );
44
+                break;
45
+            case 'y':
46
+            case 'Y':
47
+                foo << y;
48
+                format.replace( pos, 2, foo.str() );
49
+                break;
50
+            case 'w':
51
+            case 'W':
52
+                foo << w;
53
+                format.replace( pos, 2, foo.str() );
54
+                break;
55
+            case 'h':
56
+            case 'H':
57
+                foo << h;
58
+                format.replace( pos, 2, foo.str() );
59
+                break;
60
+            case 'g':
61
+            case 'G':
62
+                foo << w << 'x' << h << '+' << x << '+' << y;
63
+                format.replace( pos, 2, foo.str() );
64
+                break;
65
+            case 'i':
66
+            case 'I':
67
+                foo << window;
68
+                format.replace( pos, 2, foo.str() );
69
+                break;
70
+            case 'c':
71
+            case 'C':
72
+                format.replace( pos, 2, cancelled ? "true" : "false" );
73
+                break;
74
+            default:
75
+                fprintf( stderr, "Format error: %%%c is an unknown replacement identifier.\n", format[ pos + 1 ] );
76
+                fprintf( stderr, "Valid replacements: %%x, %%y, %%w, %%h, %%i, %%c, %%.\n" );
77
+                return 1;
78
+                break;
79
+        }
43
     }
80
     }
44
-    printf( "\n" );
45
-    printf( "ID=%i\n", window );
46
-    if ( cancelled ) {
47
-        printf( "Cancel=true\n" );
48
-    } else {
49
-        printf( "Cancel=false\n" );
81
+    pos = 0;
82
+    while ( ( pos = format.find( "\\", pos ) ) != std::string::npos ) {
83
+        if ( pos + 1 > format.size() ) {
84
+            break;
85
+        }
86
+        if ( format[ pos + 1 ] == 'n' ) {
87
+            format.replace( pos, 2, "\n" );
88
+        }
89
+        pos = pos + 1;
50
     }
90
     }
91
+    printf( "%s", format.c_str() );
92
+    return 0;
51
 }
93
 }
52
 
94
 
53
 int parseColor( std::string arg, float* r, float* g, float* b, float* a ) {
95
 int parseColor( std::string arg, float* r, float* g, float* b, float* a ) {
150
     int hmem = 0;
192
     int hmem = 0;
151
     int minimumsize = options.min_arg;
193
     int minimumsize = options.min_arg;
152
     int maximumsize = options.max_arg;
194
     int maximumsize = options.max_arg;
195
+    std::string format = options.format_arg;
153
     cmdline_parser_free( &options );
196
     cmdline_parser_free( &options );
154
 
197
 
155
     // First we set up the x interface and grab the mouse,
198
     // First we set up the x interface and grab the mouse,
156
     // if we fail for either we exit immediately.
199
     // if we fail for either we exit immediately.
157
     err = xengine->init( xdisplay.c_str() );
200
     err = xengine->init( xdisplay.c_str() );
158
     if ( err ) {
201
     if ( err ) {
159
-        printSelection( true, 0, 0, 0, 0, None );
202
+        printSelection( format, true, 0, 0, 0, 0, None );
160
         return err;
203
         return err;
161
     }
204
     }
162
     err = xengine->grabCursor( slop::Cross );
205
     err = xengine->grabCursor( slop::Cross );
163
     if ( err ) {
206
     if ( err ) {
164
-        printSelection( true, 0, 0, 0, 0, None );
207
+        printSelection( format, true, 0, 0, 0, 0, None );
165
         return err;
208
         return err;
166
     }
209
     }
167
     if ( keyboard ) {
210
     if ( keyboard ) {
181
         double starti = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
224
         double starti = double( start.tv_sec*1000000000L + start.tv_nsec )/1000000000.f;
182
         if ( timei - starti > gracetime ) {
225
         if ( timei - starti > gracetime ) {
183
             if ( ( xengine->anyKeyPressed() && keyboard ) || xengine->mouseDown( 3 ) ) {
226
             if ( ( xengine->anyKeyPressed() && keyboard ) || xengine->mouseDown( 3 ) ) {
184
-                printSelection( true, 0, 0, 0, 0, None );
227
+                printSelection( format, true, 0, 0, 0, 0, None );
185
                 fprintf( stderr, "User pressed key. Canceled selection.\n" );
228
                 fprintf( stderr, "User pressed key. Canceled selection.\n" );
186
                 state = -1;
229
                 state = -1;
187
                 running = false;
230
                 running = false;
309
                 // Delete the rectangle, which will remove it from the screen.
352
                 // Delete the rectangle, which will remove it from the screen.
310
                 delete selection;
353
                 delete selection;
311
                 // Print the selection :)
354
                 // Print the selection :)
312
-                printSelection( false, x, y, w, h, window );
355
+                printSelection( format, false, x, y, w, h, window );
313
                 break;
356
                 break;
314
             }
357
             }
315
         }
358
         }

+ 13
- 1
options.ggo View File

1
 package "slop"
1
 package "slop"
2
-version "v3.1.5"
2
+version "v3.1.7"
3
 usage "slop [options]"
3
 usage "slop [options]"
4
 description "slop (Select Operation) is an application that queries for a selection from the user and prints the region to stdout."
4
 description "slop (Select Operation) is an application that queries for a selection from the user and prints the region to stdout."
5
 versiontext "Copyright (C) 2014 Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors)"
5
 versiontext "Copyright (C) 2014 Dalton Nell, Slop Contributors (https://github.com/naelstrof/slop/graphs/contributors)"
61
     flag
61
     flag
62
     off
62
     off
63
 
63
 
64
+option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
65
+    string
66
+    default="REPLACEME"
67
+    optional
68
+
64
 text "\nExamples\n"
69
 text "\nExamples\n"
65
 text "    $ # Gray, thick, transparent border for maximum visiblity.\n"
70
 text "    $ # Gray, thick, transparent border for maximum visiblity.\n"
66
 text "    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n"
71
 text "    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n"
73
 text "\n"
78
 text "\n"
74
 text "    $ # Classic Windows XP selection.\n"
79
 text "    $ # Classic Windows XP selection.\n"
75
 text "    $ slop -l -c 0.3,0.4,0.6,0.4\n"
80
 text "    $ slop -l -c 0.3,0.4,0.6,0.4\n"
81
+text "\n"
82
+text "    $ # Change output format to use safer parsing\n"
83
+text "    $ slopoutput=$(slop -f \"%x %y %w %h\")\n"
84
+text "    $ X=$(echo $slopoutput | awk '{print $1}')\n"
85
+text "    $ Y=$(echo $slopoutput | awk '{print $2}')\n"
86
+text "    $ W=$(echo $slopoutput | awk '{print $3}')\n"
87
+text "    $ H=$(echo $slopoutput | awk '{print $4}')\n"