]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Add cupsParseOptions2.
authorMichael R Sweet <msweet@msweet.org>
Sat, 19 Oct 2024 16:36:42 +0000 (12:36 -0400)
committerMichael R Sweet <msweet@msweet.org>
Sat, 19 Oct 2024 16:36:42 +0000 (12:36 -0400)
CHANGES.md
cups/cups.h
cups/libcups2.def
cups/options.c

index c0d540b9b567bca76530b6c0fc243fd2ae7116e8..f2b9a26ad0ce7609d8d66ec4f937cdc3d001723f 100644 (file)
@@ -32,6 +32,7 @@ Changes in CUPS v2.5b1 (TBA)
 - Added a systemd slice to the systemd services included with the scheduler
 - Added localizations for deprecated IPP attributes/options (Issue #1020)
 - Added support for specifying permissions with the `cupsFileOpen` API.
+- Added new `cupsParseOptions2` API with "end" argument.
 - Updated documents (Issue #984)
 - Updated CUPS to require TLS support - OpenSSL, GNUTLS and LibreSSL are
   supported.
index 8e527a2e9ff28f16a6e0db31acd21282a032634d..1ea78f36ce50feeebefc64402422fa8af44a4d9c 100644 (file)
@@ -485,6 +485,7 @@ extern char         *cupsNotifySubject(cups_lang_t *lang, ipp_t *event) _CUPS_DEPRECATE
 extern char            *cupsNotifyText(cups_lang_t *lang, ipp_t *event) _CUPS_DEPRECATED_MSG("Use cupsLocalizeNotifyText instead.");
 
 extern int             cupsParseOptions(const char *arg, int num_options, cups_option_t **options) _CUPS_PUBLIC;
+extern int             cupsParseOptions2(const char *arg, const char **end, int num_options, cups_option_t **options) _CUPS_PUBLIC;
 extern int             cupsPrintFile(const char *name, const char *filename, const char *title, int num_options, cups_option_t *options) _CUPS_PUBLIC;
 extern int             cupsPrintFile2(http_t *http, const char *name, const char *filename, const char *title, int num_options, cups_option_t *options) _CUPS_PUBLIC;
 extern int             cupsPrintFiles(const char *name, int num_files, const char **files, const char *title, int num_options, cups_option_t *options) _CUPS_PUBLIC;
index 0ba1100201e2b8eebc17f0b29954374fd3df368d..0b08bd317d7891437d56d5def103fde60281342a 100644 (file)
@@ -11,6 +11,7 @@ _cupsCharmapFlush
 _cupsConnect
 _cupsConvertOptions
 _cupsCreateDest
+_cupsDirCreate
 _cupsEncodeOption
 _cupsEncodingName
 _cupsFilePeekAhead
@@ -359,6 +360,7 @@ cupsLangGet
 cupsLastError
 cupsLastErrorString
 cupsLocalizeDestMedia
+cupsLocalizeDestMedia2
 cupsLocalizeDestOption
 cupsLocalizeDestValue
 cupsMarkOptions
@@ -368,7 +370,21 @@ cupsMutexLock
 cupsMutexUnlock
 cupsNotifySubject
 cupsNotifyText
+cupsOAuthClearTokens
+cupsOAuthCopyAccessToken
+cupsOAuthCopyClientId
+cupsOAuthCopyRefreshToken
+cupsOAuthCopyUserId
+cupsOAuthGetAuthorizationCode
+cupsOAuthGetClientId
+cupsOAuthGetMetadata
+cupsOAuthGetTokens
+cupsOAuthMakeAuthorizationURL
+cupsOAuthMakeBase64Random
+cupsOAuthSaveClientData
+cupsOAuthSaveTokens
 cupsParseOptions
+cupsParseOptions2
 cupsPrintFile
 cupsPrintFile2
 cupsPrintFiles
@@ -481,6 +497,7 @@ httpConnect
 httpConnect2
 httpConnectAgain
 httpConnectEncrypt
+httpConnectURI
 httpCopyPeerCredentials
 httpDecode64
 httpDecode64_2
index b22d3caa7bef9a9564cd150927c842e88486b76d..0f03583c8ce7e622525b2e760321f02c9ae8a35c 100644 (file)
@@ -259,131 +259,115 @@ cupsParseOptions(
     int           num_options,         /* I - Number of options */
     cups_option_t **options)           /* O - Options found */
 {
-  char *copyarg,                       /* Copy of input string */
-       *ptr,                           /* Pointer into string */
-       *name,                          /* Pointer to name */
-       *value,                         /* Pointer to value */
-       sep,                            /* Separator character */
-       quote;                          /* Quote character */
+  return (cupsParseOptions2(arg, /*end*/NULL, num_options, options));
+}
 
 
-  DEBUG_printf("cupsParseOptions(arg=\"%s\", num_options=%d, options=%p)", arg, num_options, (void *)options);
+//
+// 'cupsParseOptions2()' - Parse options from a command-line argument.
+//
+// This function converts space-delimited name/value pairs according
+// to the PAPI text option ABNF specification. Collection values
+// ("name={a=... b=... c=...}") are stored with the curley brackets
+// intact - use @code cupsParseOptions@ on the value to extract the
+// collection attributes.
+//
+// The "end" argument, if not `NULL`, receives a pointer to the end of the
+// options.
+//
+// @since CUPS 2.5@
+//
+
+int                                    // O - Number of options found
+cupsParseOptions2(
+    const char    *arg,                        // I - Argument to parse
+    const char    **end,               // O - Pointer to end of options or `NULL` for "don't care"
+    int           num_options,         // I - Number of options
+    cups_option_t **options)           // O - Options found
+{
+  char *copyarg,                       // Copy of input string
+       *ptr,                           // Pointer into string
+       *name,                          // Pointer to name
+       *value,                         // Pointer to value
+       sep,                            // Separator character
+       quote;                          // Quote character
 
- /*
-  * Range check input...
-  */
+
+  // Range check input...
+  if (end)
+    *end = NULL;
 
   if (!arg)
-  {
-    DEBUG_printf("1cupsParseOptions: Returning %d", num_options);
     return (num_options);
-  }
 
-  if (!options || num_options < 0)
-  {
-    DEBUG_puts("1cupsParseOptions: Returning 0");
+  if (!options)
     return (0);
-  }
-
- /*
-  * Make a copy of the argument string and then divide it up...
-  */
 
+  // Make a copy of the argument string and then divide it up...
   if ((copyarg = strdup(arg)) == NULL)
   {
-    DEBUG_puts("1cupsParseOptions: Unable to copy arg string");
-    DEBUG_printf("1cupsParseOptions: Returning %d", num_options);
+    DEBUG_puts("1cupsParseOptions2: Unable to copy arg string");
     return (num_options);
   }
 
   if (*copyarg == '{')
-  {
-   /*
-    * Remove surrounding {} so we can parse "{name=value ... name=value}"...
-    */
-
-    if ((ptr = copyarg + strlen(copyarg) - 1) > copyarg && *ptr == '}')
-    {
-      *ptr = '\0';
-      ptr  = copyarg + 1;
-    }
-    else
-      ptr = copyarg;
-  }
+    ptr  = copyarg + 1;
   else
     ptr = copyarg;
 
- /*
-  * Skip leading spaces...
-  */
-
+  // Skip leading spaces...
   while (_cups_isspace(*ptr))
     ptr ++;
 
- /*
-  * Loop through the string...
-  */
-
+  // Loop through the string...
   while (*ptr != '\0')
   {
-   /*
-    * Get the name up to a SPACE, =, or end-of-string...
-    */
-
+    // Get the name up to a SPACE, =, or end-of-string...
     name = ptr;
     while (!strchr("\f\n\r\t\v =", *ptr) && *ptr)
       ptr ++;
 
-   /*
-    * Avoid an empty name...
-    */
-
+    // Avoid an empty name...
     if (ptr == name)
       break;
 
-   /*
-    * Skip trailing spaces...
-    */
+    // End after the closing brace...
+    if (*ptr == '}' && *copyarg == '{')
+    {
+      ptr ++;
+      break;
+    }
 
+    // Skip trailing spaces...
     while (_cups_isspace(*ptr))
       *ptr++ = '\0';
 
     if ((sep = *ptr) == '=')
       *ptr++ = '\0';
 
-    DEBUG_printf("2cupsParseOptions: name=\"%s\"", name);
-
     if (sep != '=')
     {
-     /*
-      * Boolean option...
-      */
-
+      // Boolean option...
       if (!_cups_strncasecmp(name, "no", 2))
-        num_options = cupsAddOption(name + 2, "false", num_options,
-                                   options);
+        num_options = cupsAddOption(name + 2, "false", num_options, options);
       else
         num_options = cupsAddOption(name, "true", num_options, options);
 
       continue;
     }
 
-   /*
-    * Remove = and parse the value...
-    */
-
+    // Remove = and parse the value...
     value = ptr;
 
     while (*ptr && !_cups_isspace(*ptr))
     {
       if (*ptr == ',')
+      {
         ptr ++;
+      }
       else if (*ptr == '\'' || *ptr == '\"')
       {
-       /*
-       * Quoted string constant...
-       */
-
+        // Quoted string constant...
        quote = *ptr;
        _cups_strcpy(ptr, ptr + 1);
 
@@ -400,16 +384,15 @@ cupsParseOptions(
       }
       else if (*ptr == '{')
       {
-       /*
-       * Collection value...
-       */
-
-       int depth;
+        // Collection value...
+       int depth;                      // Nesting depth for braces
 
        for (depth = 0; *ptr; ptr ++)
        {
          if (*ptr == '{')
+         {
            depth ++;
+         }
          else if (*ptr == '}')
          {
            depth --;
@@ -420,15 +403,14 @@ cupsParseOptions(
            }
          }
          else if (*ptr == '\\' && ptr[1])
+         {
            _cups_strcpy(ptr, ptr + 1);
+         }
        }
       }
       else
       {
-       /*
-       * Normal space-delimited string...
-       */
-
+        // Normal space-delimited string...
        while (*ptr && !_cups_isspace(*ptr))
        {
          if (*ptr == '\\' && ptr[1])
@@ -442,31 +424,21 @@ cupsParseOptions(
     if (*ptr != '\0')
       *ptr++ = '\0';
 
-    DEBUG_printf("2cupsParseOptions: value=\"%s\"", value);
-
-   /*
-    * Skip trailing whitespace...
-    */
-
+    // Skip trailing whitespace...
     while (_cups_isspace(*ptr))
       ptr ++;
 
-   /*
-    * Add the string value...
-    */
-
+    // Add the string value...
     num_options = cupsAddOption(name, value, num_options, options);
   }
 
- /*
-  * Free the copy of the argument we made and return the number of options
-  * found.
-  */
+  // Save the progress in the input string...
+  if (end)
+    *end = arg + (ptr - copyarg);
 
+  // Free the copy of the argument we made and return the number of options found.
   free(copyarg);
 
-  DEBUG_printf("1cupsParseOptions: Returning %d", num_options);
-
   return (num_options);
 }