[MPlayer-dev-eng] [PATCH] new subopt type for malloced string

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Sun Jan 16 14:35:46 CET 2005


Hi,
The attached patch moves some duplicated code to subopt_parser.c, by
providing a new opt type, malloced, zero terminated string.
You need to free it, and you must initialize it either to NULL or a
malloced buffer (e.g. via strdup).
I'd also like to extend the documentation of the test function to make
it say: "it may also modify the argument within the limits that apply to
initializing variables and modifying them after the parsing".
The last part is because strarg_t.str may not be modified, and for the
OPT_ARG_MSTRZ arg it must still point to a malloced buffer.

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: subopt-helper.c
===================================================================
RCS file: /cvsroot/mplayer/main/subopt-helper.c,v
retrieving revision 1.2
diff -u -r1.2 subopt-helper.c
--- subopt-helper.c	1 Jan 2005 19:03:22 -0000	1.2
+++ subopt-helper.c	16 Jan 2005 12:54:35 -0000
@@ -22,6 +22,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include <assert.h>
 
 #ifndef MPDEBUG
@@ -144,6 +145,23 @@
                 last = parse_str( &str[parse_pos],
                                   (strarg_t *)opts[idx].valp );
                 break;
+              case OPT_ARG_MSTRZ:
+                {
+                  char **valp = opts[idx].valp;
+                  strarg_t tmp;
+                  tmp.str = NULL;
+                  tmp.len = 0;
+                  last = parse_str( &str[parse_pos], &tmp );
+                  if (*valp)
+                    free(*valp);
+                  *valp = NULL;
+                  if (tmp.str && tmp.len > 0) {
+                    *valp = malloc(tmp.len + 1);
+                    memcpy(*valp, tmp.str, tmp.len);
+                    *valp[tmp.len] = 0;
+                  }
+                  break;
+                }
               default:
                 assert( 0 && "Arg type of suboption doesn't exist!" );
                 last = NULL; // break parsing!
@@ -237,7 +255,7 @@
     match = &str[strlen(str)];
 
   // empty string or too long
-  if ((match == str) || (match - str > 255))
+  if ((match == str) || (match - str > INT_MAX))
     return NULL;
 
   valp->len = match - str;
Index: subopt-helper.h
===================================================================
RCS file: /cvsroot/mplayer/main/subopt-helper.h,v
retrieving revision 1.2
diff -u -r1.2 subopt-helper.h
--- subopt-helper.h	31 Dec 2004 14:57:12 -0000	1.2
+++ subopt-helper.h	16 Jan 2005 12:54:35 -0000
@@ -12,6 +12,7 @@
 #define OPT_ARG_BOOL 0
 #define OPT_ARG_INT  1
 #define OPT_ARG_STR  2
+#define OPT_ARG_MSTRZ 3 ///< A malloced, zero terminated string, use free()!
 
 typedef int (*opt_test_f)(void *);
 
@@ -34,7 +35,7 @@
 /*------------------ arg specific types and declaration -------------------*/
 typedef struct strarg_s
 {
-  unsigned char len; ///< length of the string determined by the parser
+  int len; ///< length of the string determined by the parser
   char const * str;  ///< pointer to position inside the parse string
 } strarg_t;
 
Index: libao2/ao_pcm.c
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/ao_pcm.c,v
retrieving revision 1.28
diff -u -r1.28 ao_pcm.c
--- libao2/ao_pcm.c	3 Jan 2005 14:16:06 -0000	1.28
+++ libao2/ao_pcm.c	16 Jan 2005 12:54:43 -0000
@@ -80,27 +80,18 @@
 // return: 1=success 0=fail
 static int init(int rate,int channels,int format,int flags){
 	int bits;
-	strarg_t file;
 	opt_t subopts[] = {
 	  {"waveheader", OPT_ARG_BOOL, &ao_pcm_waveheader, NULL},
-	  {"file",       OPT_ARG_STR,  &file,              NULL},
+	  {"file",       OPT_ARG_MSTRZ, &ao_outputfilename, NULL},
 	  {NULL}
 	};
 	// set defaults
 	ao_pcm_waveheader = 1;
-	file.str = NULL;
-	file.len = 0;
+	ao_outputfilename =
+	      strdup((ao_pcm_waveheader)?"audiodump.wav":"audiodump.pcm");
 	if (subopt_parse(ao_subdevice, subopts) != 0) {
 	  return 0;
 	}
-	if (file.len > 0) {
-	ao_outputfilename = malloc(file.len + 1);
-	memcpy(ao_outputfilename, file.str, file.len);
-	ao_outputfilename[file.len] = 0;
-	}
-	else
-	  ao_outputfilename =
-	      strdup((ao_pcm_waveheader)?"audiodump.wav":"audiodump.pcm");
 
 	/* bits is only equal to format if (format == 8) or (format == 16);
 	   this means that the following "if" is a kludge and should
Index: libvo/vo_jpeg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_jpeg.c,v
retrieving revision 1.24
diff -u -r1.24 vo_jpeg.c
--- libvo/vo_jpeg.c	15 Jan 2005 23:53:08 -0000	1.24
+++ libvo/vo_jpeg.c	16 Jan 2005 12:55:00 -0000
@@ -325,7 +325,6 @@
 
 static uint32_t preinit(const char *arg)
 {
-    strarg_t outdir = {0, NULL}, subdirs = {0, NULL};
     opt_t subopts[] = {
         {"progressive", OPT_ARG_BOOL,   &jpeg_progressive_mode, NULL},
         {"baseline",    OPT_ARG_BOOL,   &jpeg_baseline,         NULL},
@@ -335,8 +334,8 @@
                                                 (opt_test_f)int_zero_hundred},
         {"quality",     OPT_ARG_INT,    &jpeg_quality,
                                                 (opt_test_f)int_zero_hundred},
-        {"outdir",      OPT_ARG_STR,    &outdir,                NULL},
-        {"subdirs",     OPT_ARG_STR,    &subdirs,               NULL},
+        {"outdir",      OPT_ARG_MSTRZ,  &jpeg_outdir,           NULL},
+        {"subdirs",     OPT_ARG_MSTRZ,  &jpeg_subdirs,          NULL},
         {"maxfiles",    OPT_ARG_INT,    &jpeg_maxfiles, (opt_test_f)int_pos},
         {NULL}
     };
@@ -351,25 +350,13 @@
     jpeg_smooth = 0;
     jpeg_quality = 75;
     jpeg_maxfiles = 1000;
+    jpeg_outdir = strdup(".");
+    jpeg_subdirs = NULL;
 
     if (subopt_parse(arg, subopts) != 0) {
         return -1;
     }
 
-    if (outdir.len) {
-        jpeg_outdir = malloc(outdir.len + 1);
-        memcpy(jpeg_outdir, outdir.str, outdir.len);
-        jpeg_outdir[outdir.len] = '\0';
-    } else {
-        jpeg_outdir = strdup(".");
-    }
-
-    if (subdirs.len) {
-        jpeg_subdirs = malloc(subdirs.len + 1);
-        memcpy(jpeg_subdirs, subdirs.str, subdirs.len);
-        jpeg_subdirs[subdirs.len] = '\0';
-    }
-
     if (jpeg_progressive_mode) info_message = MSGTR_VO_JPEG_ProgressiveJPEG;
     else info_message = MSGTR_VO_JPEG_NoProgressiveJPEG;
     mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name, info_message);
Index: libvo/vo_md5sum.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_md5sum.c,v
retrieving revision 1.2
diff -u -r1.2 vo_md5sum.c
--- libvo/vo_md5sum.c	15 Jan 2005 23:54:49 -0000	1.2
+++ libvo/vo_md5sum.c	16 Jan 2005 12:55:01 -0000
@@ -103,9 +103,8 @@
 
 static uint32_t preinit(const char *arg)
 {
-    strarg_t outfile = {0, NULL};
     opt_t subopts[] = {
-        {"outfile",     OPT_ARG_STR,    &outfile,   NULL},
+        {"outfile",     OPT_ARG_MSTRZ,    &md5sum_outfile,   NULL},
         {NULL}
     };
 
@@ -114,18 +113,11 @@
     mp_msg(MSGT_VO, MSGL_INFO, "%s: %s\n", info.short_name,
                                             MSGTR_VO_ParsingSuboptions);
 
+    md5sum_outfile = strdup("md5sums");
     if (subopt_parse(arg, subopts) != 0) {
         return -1;
     }
 
-    if (outfile.len) {
-        md5sum_outfile = malloc(outfile.len + 1);
-        memcpy(md5sum_outfile, outfile.str, outfile.len);
-        md5sum_outfile[outfile.len] = '\0';
-    } else {
-        md5sum_outfile = strdup("md5sums");
-    }
-
     mp_msg(MSGT_VO, MSGL_V, "%s: outfile --> %s\n", info.short_name,
                                                             md5sum_outfile);
 
Index: libvo/vo_pnm.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_pnm.c,v
retrieving revision 1.3
diff -u -r1.3 vo_pnm.c
--- libvo/vo_pnm.c	15 Jan 2005 21:21:07 -0000	1.3
+++ libvo/vo_pnm.c	16 Jan 2005 12:55:02 -0000
@@ -130,16 +130,14 @@
 {
     int ppm_type = 0, pgm_type = 0, pgmyuv_type = 0,
         raw_mode = 0, ascii_mode = 0;
-    strarg_t outdir  = {0, NULL},
-             subdirs = {0, NULL};
     opt_t subopts[] = {
         {"ppm",         OPT_ARG_BOOL,   &ppm_type,      NULL},
         {"pgm",         OPT_ARG_BOOL,   &pgm_type,      NULL},
         {"pgmyuv",      OPT_ARG_BOOL,   &pgmyuv_type,   NULL},
         {"raw",         OPT_ARG_BOOL,   &raw_mode,      NULL},
         {"ascii",       OPT_ARG_BOOL,   &ascii_mode,    NULL},
-        {"outdir",      OPT_ARG_STR,    &outdir,        NULL},
-        {"subdirs",     OPT_ARG_STR,    &subdirs,       NULL},
+        {"outdir",      OPT_ARG_MSTRZ,  &pnm_outdir,    NULL},
+        {"subdirs",     OPT_ARG_MSTRZ,  &pnm_subdirs,   NULL},
         {"maxfiles",    OPT_ARG_INT,    &pnm_maxfiles,  (opt_test_f)int_pos},
         {NULL}
     };
@@ -149,6 +147,8 @@
                                             MSGTR_VO_ParsingSuboptions);
 
     pnm_maxfiles = 1000;
+    pnm_outdir = strdup(".");
+    pnm_subdirs = NULL;
 
     if (subopt_parse(arg, subopts) != 0) {
         return -1;
@@ -163,20 +163,6 @@
     if (ascii_mode)  pnm_mode     = PNM_ASCII_MODE;
     if (raw_mode)    pnm_mode     = PNM_RAW_MODE;
 
-    if (outdir.len) {
-        pnm_outdir = malloc(outdir.len + 1);
-        memcpy(pnm_outdir, outdir.str, outdir.len);
-        pnm_outdir[outdir.len] = '\0';
-    } else {
-        pnm_outdir = strdup(".");
-    }
-
-    if (subdirs.len) {
-        pnm_subdirs = malloc(subdirs.len + 1);
-        memcpy(pnm_subdirs, subdirs.str, subdirs.len);
-        pnm_subdirs[subdirs.len] = '\0';
-    }
-
     switch (pnm_mode) {
         case PNM_ASCII_MODE:
             info_message = MSGTR_VO_PNM_ASCIIMode;
Index: libvo/vo_yuv4mpeg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_yuv4mpeg.c,v
retrieving revision 1.20
diff -u -r1.20 vo_yuv4mpeg.c
--- libvo/vo_yuv4mpeg.c	31 Dec 2004 14:54:58 -0000	1.20
+++ libvo/vo_yuv4mpeg.c	16 Jan 2005 12:55:02 -0000
@@ -141,12 +141,12 @@
 	write_bytes = image_width * image_height * 3 / 2;
 	image = malloc(write_bytes);
 
-	yuv_out = fopen(yuv_filename ? yuv_filename : "stream.yuv", "wb");
+	yuv_out = fopen(yuv_filename, "wb");
 	if (!yuv_out || image == 0) 
 	{
 		mp_msg(MSGT_VO,MSGL_FATAL,
 			MSGTR_VO_YUV4MPEG_OutFileOpenError,
-			yuv_filename ? yuv_filename : "stream.yuv");
+			yuv_filename);
 		return -1;
 	}
 	image_y = image;
@@ -496,17 +496,16 @@
 static uint32_t preinit(const char *arg)
 {
   int il, il_bf;
-  strarg_t file;
   opt_t subopts[] = {
     {"interlaced",    OPT_ARG_BOOL, &il,    NULL},
     {"interlaced_bf", OPT_ARG_BOOL, &il_bf, NULL},
-    {"file",          OPT_ARG_STR,  &file,  NULL},
+    {"file",          OPT_ARG_MSTRZ,  &yuv_filename,  NULL},
     {NULL}
   };
 
   il = 0;
   il_bf = 0;
-  file.len = 0;
+  yuv_filename = strdup("stream.yuv");
   if (subopt_parse(arg, subopts) != 0) {
     mp_msg(MSGT_VO, MSGL_FATAL, MSGTR_VO_YUV4MPEG_UnknownSubDev, arg); 
     return -1;
@@ -517,12 +516,6 @@
     config_interlace = Y4M_ILACE_TOP_FIRST;
   if (il_bf)
     config_interlace = Y4M_ILACE_BOTTOM_FIRST;
-  yuv_filename = NULL;
-  if (file.len > 0) {
-    yuv_filename = malloc(file.len + 1);
-    memcpy(yuv_filename, file.str, file.len);
-    yuv_filename[file.len] = 0;
-  }
 
     /* Inform user which output mode is used */
     switch (config_interlace)


More information about the MPlayer-dev-eng mailing list