Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 23643)
+++ /trunk/include/iprt/err.h	(revision 23644)
@@ -1146,12 +1146,14 @@
 /** @name RTGetOpt status codes
  * @{ */
-/** RTGetOpt: command line option not recognized. */
+/** RTGetOpt: Command line option not recognized. */
 #define VERR_GETOPT_UNKNOWN_OPTION              (-825)
-/** RTGetOpt: command line option needs argument. */
+/** RTGetOpt: Command line option needs argument. */
 #define VERR_GETOPT_REQUIRED_ARGUMENT_MISSING   (-826)
-/** RTGetOpt: command line option has argument with bad format. */
+/** RTGetOpt: Command line option has argument with bad format. */
 #define VERR_GETOPT_INVALID_ARGUMENT_FORMAT     (-827)
 /** RTGetOpt: Not an option. */
 #define VINF_GETOPT_NOT_OPTION                  828
+/** RTGetOpt: Command line option needs an index. */
+#define VERR_GETOPT_INDEX_MISSING               (-829)
 /** @} */
 
Index: /trunk/include/iprt/getopt.h
===================================================================
--- /trunk/include/iprt/getopt.h	(revision 23643)
+++ /trunk/include/iprt/getopt.h	(revision 23644)
@@ -92,6 +92,12 @@
 /** Treat the value as decimal - only applicable with the RTGETOPT_REQ_*INT*. */
 #define RTGETOPT_FLAG_DEC                       RT_BIT(18)
+/** The index value is attached to the argument - only valid for long arguments. */
+#define RTGETOPT_FLAG_INDEX                     RT_BIT(19)
 /** Mask of valid bits - for validation. */
-#define RTGETOPT_VALID_MASK                     ( RTGETOPT_REQ_MASK | RTGETOPT_FLAG_HEX | RTGETOPT_FLAG_OCT | RTGETOPT_FLAG_DEC )
+#define RTGETOPT_VALID_MASK                     (  RTGETOPT_REQ_MASK \
+                                                 | RTGETOPT_FLAG_HEX \
+                                                 | RTGETOPT_FLAG_OCT \
+                                                 | RTGETOPT_FLAG_DEC \
+                                                 | RTGETOPT_FLAG_INDEX)
 /** @} */
 
@@ -193,4 +199,6 @@
     /** The option definition which matched. NULL otherwise. */
     PCRTGETOPTDEF   pDef;
+    /** The index of an index option, otherwise UINT64_MAX. */
+    uint64_t        uIndex;
     /* More members will be added later for dealing with initial
        call, optional sorting, '--' and so on. */
Index: /trunk/src/VBox/Runtime/common/misc/getopt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/getopt.cpp	(revision 23643)
+++ /trunk/src/VBox/Runtime/common/misc/getopt.cpp	(revision 23644)
@@ -192,13 +192,38 @@
                  * A value is required with the argument. We're trying to be very
                  * understanding here and will permit any of the following:
-                 *      --long:value,  --long=value, --long value,
-                 *      --long: value, --long= value
+                 *      --long12:value,  --long12=value, --long12 value,
+                 *      --long:value,    --long=value,   --long value,
+                 *      --long: value,   --long= value
+                 *
+                 * If the option is index, then all trailing chars must be
+                 * digits.  For error reporting reasons we also match where
+                 * there is no index.
                  */
                 size_t cchLong = strlen(pOpt->pszLong);
-                if (    !strncmp(pszOption, pOpt->pszLong, cchLong)
-                    && (   pszOption[cchLong] == '\0'
+                if (!strncmp(pszOption, pOpt->pszLong, cchLong))
+                {
+                    if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
+                        while (RT_C_IS_DIGIT(pszOption[cchLong]))
+                            cchLong++;
+                    if (   pszOption[cchLong] == '\0'
                         || pszOption[cchLong] == ':'
-                        || pszOption[cchLong] == '='))
-                    return pOpt;
+                        || pszOption[cchLong] == '=')
+                        return pOpt;
+                }
+            }
+            else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
+            {
+                /*
+                 * The option takes an index but no value.
+                 * As above, we also match where there is no index.
+                 */
+                size_t cchLong = strlen(pOpt->pszLong);
+                if (!strncmp(pszOption, pOpt->pszLong, cchLong))
+                {
+                    while (RT_C_IS_DIGIT(pszOption[cchLong]))
+                        cchLong++;
+                    if (pszOption[cchLong] == '\0')
+                        return pOpt;
+                }
             }
             else if (!strcmp(pszOption, pOpt->pszLong))
@@ -234,5 +259,10 @@
 RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion)
 {
+    /*
+     * Reset the variables kept in state.
+     */
     pState->pDef = NULL;
+    pState->uIndex = UINT64_MAX;
+
     /*
      * Make sure the union is completely cleared out, whatever happens below.
@@ -338,14 +368,45 @@
             {
                 size_t cchLong = strlen(pOpt->pszLong);
-                if (    pszArgThis[cchLong]     == '\0'
-                    ||  pszArgThis[cchLong + 1] == '\0')
-                {
-                    if (iThis + 1 >= pState->argc)
-                        return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
-                    pszValue = pState->argv[iThis + 1];
-                    pState->iNext++;
-                }
-                else /* same argument. */
-                    pszValue = &pszArgThis[cchLong + 1];
+                if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
+                {
+
+                    if (pszArgThis[cchLong] == '\0')
+                        return VERR_GETOPT_INDEX_MISSING;
+
+                    uint64_t uIndex;
+                    char *pszRet = NULL;
+                    int rc = RTStrToUInt64Ex(&pszArgThis[cchLong], &pszRet, 10, &uIndex);
+                    if (rc == VWRN_TRAILING_CHARS)
+                    {
+                        if (   pszRet[0] != ':'
+                            && pszRet[0] != '=')
+                            return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
+                        pState->uIndex = uIndex;
+                        pszValue = pszRet + 1;
+                    }
+                    else if (rc == VINF_SUCCESS)
+                    {
+                        if (iThis + 1 >= pState->argc)
+                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
+                        pState->uIndex = uIndex;
+                        pszValue = pState->argv[iThis + 1];
+                        pState->iNext++;
+                    }
+                    else
+                        AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
+                }
+                else
+                {
+                    if (    pszArgThis[cchLong]     == '\0'
+                        ||  pszArgThis[cchLong + 1] == '\0')
+                    {
+                        if (iThis + 1 >= pState->argc)
+                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
+                        pszValue = pState->argv[iThis + 1];
+                        pState->iNext++;
+                    }
+                    else /* same argument. */
+                        pszValue = &pszArgThis[cchLong + 1];
+                }
             }
 
@@ -356,5 +417,8 @@
              * generic ints as octals.
              */
-            switch (pOpt->fFlags & (RTGETOPT_REQ_MASK | RTGETOPT_FLAG_HEX | RTGETOPT_FLAG_OCT | RTGETOPT_FLAG_DEC))
+            switch (pOpt->fFlags & (  RTGETOPT_REQ_MASK
+                                    | RTGETOPT_FLAG_HEX
+                                    | RTGETOPT_FLAG_DEC
+                                    | RTGETOPT_FLAG_OCT))
             {
                 case RTGETOPT_REQ_STRING:
@@ -480,4 +544,17 @@
             }
         }
+        else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
+        {
+            size_t cchLong = strlen(pOpt->pszLong);
+            if (pszArgThis[cchLong] == '\0')
+                return VERR_GETOPT_INDEX_MISSING;
+
+            uint64_t uIndex;
+            char *pszRet = NULL;
+            if (RTStrToUInt64Full(&pszArgThis[cchLong], 10, &uIndex) == VINF_SUCCESS)
+                pState->uIndex = uIndex;
+            else
+                AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
+        }
 
         pState->pDef = pOpt;
Index: /trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp	(revision 23643)
+++ /trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp	(revision 23644)
@@ -88,4 +88,10 @@
         { "--gateway",          'g', RTGETOPT_REQ_IPV4ADDR },
         { "--mac",              'm', RTGETOPT_REQ_MACADDR },
+        { "--strindex",         400, RTGETOPT_REQ_STRING  | RTGETOPT_FLAG_INDEX },
+        { "strindex",           400, RTGETOPT_REQ_STRING  | RTGETOPT_FLAG_INDEX },
+        { "--intindex",         401, RTGETOPT_REQ_INT32   | RTGETOPT_FLAG_INDEX },
+        { "--macindex",         402, RTGETOPT_REQ_MACADDR | RTGETOPT_FLAG_INDEX },
+        { "--indexnovalue",     403, RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_INDEX },
+        { "--macindexnegative", 404, RTGETOPT_REQ_NOTHING },
     };
 
@@ -129,4 +135,15 @@
         "--mac:1:::::c",
 
+        "--strindex786",    "string4",
+        "--strindex786:string5",
+        "--strindex786=string6",
+        "strindex687",      "string7",
+        "strindex687:string8",
+        "strindex687=string9",
+        "--intindex137",    "1000",
+        "--macindex138",    "08:0:27:00:ab:f3",
+        "--indexnovalue1",
+        "--macindexnegative",
+
         NULL
     };
@@ -137,6 +154,8 @@
     CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
     CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string1"));
+    CHECK(GetState.uIndex == UINT64_MAX);
     CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
     CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string2"));
+    CHECK(GetState.uIndex == UINT64_MAX);
 
     /* -i */
@@ -222,4 +241,48 @@
           && Val.MacAddr.au8[5] == 0x0c);
 
+    /* string with indexed argument */
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string4"));
+    CHECK(GetState.uIndex == 786);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string5"));
+    CHECK(GetState.uIndex == 786);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string6"));
+    CHECK(GetState.uIndex == 786);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string7"));
+    CHECK(GetState.uIndex == 687);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string8"));
+    CHECK(GetState.uIndex == 687);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
+    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string9"));
+    CHECK(GetState.uIndex == 687);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 401, 2);
+    CHECK(Val.i32 == 1000);
+    CHECK(GetState.uIndex == 137);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 402, 2);
+    CHECK(   Val.MacAddr.au8[0] == 0x08
+          && Val.MacAddr.au8[1] == 0x00
+          && Val.MacAddr.au8[2] == 0x27
+          && Val.MacAddr.au8[3] == 0x00
+          && Val.MacAddr.au8[4] == 0xab
+          && Val.MacAddr.au8[5] == 0xf3);
+    CHECK(GetState.uIndex == 138);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 403, 1);
+    CHECK(GetState.uIndex == 1);
+
+    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 404, 1);
+    CHECK(GetState.uIndex == UINT64_MAX);
+
     /* the end */
     CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
