Diff for /XML/uri.c between versions 1.3 and 1.4

version 1.3, 2000/03/04 16:54:07 version 1.4, 2000/03/16 13:03:03
Line 18 Line 18
 #include <stdio.h>  #include <stdio.h>
 #include <string.h>  #include <string.h>
   
 #include "tree.h"  #include "xmlmemory.h"
   #include "uri.h"
   
 /**  /**
  * alpha    = lowalpha | upalpha   * alpha    = lowalpha | upalpha
Line 32 Line 33
  *            "u" | "v" | "w" | "x" | "y" | "z"   *            "u" | "v" | "w" | "x" | "y" | "z"
  */   */
   
 #define IS_LOWAPHA(x) ((x >= 'a') && (x <= 'z'))  #define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
   
 /**  /**
  * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |   * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |
  *           "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |   *           "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |
  *           "U" | "V" | "W" | "X" | "Y" | "Z"   *           "U" | "V" | "W" | "X" | "Y" | "Z"
  */   */
 #define IS_UPALPHA(x) ((x >= 'A') && (x <= 'Z'))  #define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))
   
 /**  /**
  * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"   * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
  */   */
   
 #define IS_DIGIT(x) ((x >= '0') && (x <= '9'))  #define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
   
 /**  /**
  * alphanum = alpha | digit   * alphanum = alpha | digit
Line 54 Line 55
 #define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))  #define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
   
 /**  /**
  * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |   * he(x) = digit | "A" | "B" | "C" | "D" | "E" | "F" |
  *               "a" | "b" | "c" | "d" | "e" | "f"   *               "a" | "b" | "c" | "d" | "e" | "f"
  */   */
   
 #define IS_HEX(x) ((IS_DIGIT(x)) || ((x >= 'a') && (x <= 'f')) || \  #define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \
             ((x >= 'A') && (x <= 'F')))              (((x) >= 'A') && ((x) <= 'F')))
   
 /**  /**
  * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"   * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
  */   */
   
 #define IS_MARK(x) ((x == '-') || (x == '_') || (x == '.') || (x == '!') || \  #define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') ||     \
       (x == '~') || (x == '*') || (x == '\'') || (x == '(') || (x == ')'))      ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') ||    \
       ((x) == '(') || ((x) == ')'))
   
   
 /**  /**
  * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","   * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
  */   */
   
 #define IS_RESERVED(x) ((x == ';') || (x == '/') || (x == '?') || \  #define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
           (x == ':') || (x == '@') || (x == '&') || (x == '=') || \          ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
           (x == '+') || (x == '$') || (x == ','))          ((x) == '+') || ((x) == '$') || ((x) == ','))
   
 /**  /**
  * unreserved = alphanum | mark   * unreserved = alphanum | mark
Line 83 Line 85
   
 #define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))  #define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
   
   /**
    * escaped = "%" hex hex
    */
   
   #define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) &&             \
               (IS_HEX((p)[2])))
   
   /**
    * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
    *                        "&" | "=" | "+" | "$" | ","
    */
   #define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\
                   ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\
                   ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\
                   ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
   
   /**
    * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
    */
   #define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||        \
                   ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\
                   ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\
                   ((*(p) == ',')))
   
   /**
    * rel_segment   = 1*( unreserved | escaped |
    *                 ";" | "@" | "&" | "=" | "+" | "$" | "," )
    */
   
   #define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||      \
             ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||      \
             ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||      \
             ((*(p) == ',')))
   
   /**
    * scheme = alpha *( alpha | digit | "+" | "-" | "." )
    */
   
   #define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) ||                 \
                         ((x) == '+') || ((x) == '-') || ((x) == '.'))
   
   /**
    * reg_name = 1*( unreserved | escaped | "$" | "," |
    *                ";" | ":" | "@" | "&" | "=" | "+" )
    */
   
   #define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||     \
          ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||         \
          ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||         \
          ((*(p) == '=')) || ((*(p) == '+')))
   
   /**
    * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" |
    *                      "+" | "$" | "," )
    */
   #define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||     \
          ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) ||         \
          ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||         \
          ((*(p) == ',')))
   
   /**
    * uric = reserved | unreserved | escaped
    */
   
   #define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||         \
                       (IS_RESERVED(*(p))))
   
   /**
    * Skip to next pointer char, handle escaped sequences
    */
   
   #define NEXT(p) ((*p == '%')? p += 3 : p++)
   
 /**  /**
  *   *
       URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]  
       absoluteURI   = scheme ":" ( hier_part | opaque_part )  
       relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]        relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]
   
       hier_part     = ( net_path | abs_path ) [ "?" query ]  
       opaque_part   = uric_no_slash *uric  
   
       net_path      = "//" authority [ abs_path ]        net_path      = "//" authority [ abs_path ]
       abs_path      = "/"  path_segments        abs_path      = "/"  path_segments
       rel_path      = rel_segment [ abs_path ]        rel_path      = rel_segment [ abs_path ]
   
       rel_segment   = 1*( unreserved | escaped |   *    rel_segment   = 1*( unreserved | escaped |
                           ";" | "@" | "&" | "=" | "+" | "$" | "," )   *                        ";" | "@" | "&" | "=" | "+" | "$" | "," )
    *
       scheme        = alpha *( alpha | digit | "+" | "-" | "." )  
   
       authority     = server | reg_name        authority     = server | reg_name
   
       reg_name      = 1*( unreserved | escaped | "$" | "," |   *    reg_name      = 1*( unreserved | escaped | "$" | "," |
                           ";" | ":" | "@" | "&" | "=" | "+" )   *                        ";" | ":" | "@" | "&" | "=" | "+" )
   
       server        = [ [ userinfo "@" ] hostport ]        server        = [ [ userinfo "@" ] hostport ]
       userinfo      = *( unreserved | escaped |   *    userinfo      = *( unreserved | escaped |
                          ";" | ":" | "&" | "=" | "+" | "$" | "," )   *                       ";" | ":" | "&" | "=" | "+" | "$" | "," )
   
       hostport      = host [ ":" port ]        hostport      = host [ ":" port ]
       host          = hostname | IPv4address        host          = hostname | IPv4address
Line 120 Line 187
       port          = *digit        port          = *digit
   
       path          = [ abs_path | opaque_part ]        path          = [ abs_path | opaque_part ]
       path_segments = segment *( "/" segment )  
       segment       = *pchar *( ";" param )  
       param         = *pchar  
   
       query         = *uric        query         = *uric
   
       fragment      = *uric       */
   
   /**
    * xmlCreateURI:
    *
    * Simply creates an empty xmlURI
    *
    * Returns the new structure or NULL in case of error
    */
   xmlURIPtr
   xmlCreateURI(void) {
       xmlURIPtr ret;
   
       ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
       if (ret == NULL) {
           fprintf(stderr, "xmlCreateURI: out of memory\n");
           return(NULL);
       }
       memset(ret, 0, sizeof(xmlURI));
       return(ret);
   }
   
   /**
    * xmlCleanURI:
    * @uri:  pointer to an xmlURI
    *
    * Make sure the xmlURI struct is free of content
    */
   void
   xmlCleanURI(xmlURIPtr uri) {
       if (uri == NULL) return;
   
       if (uri->scheme != NULL) xmlFree(uri->scheme);
       uri->scheme = NULL;
       if (uri->server != NULL) xmlFree(uri->server);
       uri->server = NULL;
       if (uri->path != NULL) xmlFree(uri->path);
       uri->path = NULL;
       if (uri->fragment != NULL) xmlFree(uri->fragment);
       uri->fragment = NULL;
       if (uri->opaque != NULL) xmlFree(uri->opaque);
       uri->opaque = NULL;
   }
   
   /**
    * xmlFreeURI:
    * @uri:  pointer to an xmlURI
    *
    * Free up the xmlURI struct
    */
   void
   xmlFreeURI(xmlURIPtr uri) {
       if (uri == NULL) return;
   
       if (uri->scheme != NULL) xmlFree(uri->scheme);
       if (uri->server != NULL) xmlFree(uri->server);
       if (uri->path != NULL) xmlFree(uri->path);
       if (uri->fragment != NULL) xmlFree(uri->fragment);
       if (uri->opaque != NULL) xmlFree(uri->opaque);
       memset(uri, -1, sizeof(xmlURI));
       xmlFree(uri);
   }
   
       Macroifiables  /**
       =============   * xmlURIUnescape:
    * @str:  the string to unescape
    * @len:   the lenght in bytes to unescape (or <= 0 to indicate full string)
    * @target:  optionnal destination buffer
    *
    * Unescaping routine, does not do validity checks !
    *
    * Returns an copy of the string, but unescaped
    */
   char *
   xmlURIUnescape(const char *str, int len, char *target) {
       char *ret, *out;
       const char *in;
   
       if (str == NULL)
           return(NULL);
       if (len <= 0) len = strlen(str);
   
       if (target == NULL) {
           ret = (char *) xmlMalloc(len + 1);
           if (ret == NULL) {
               fprintf(stderr, "xmlURIUnescape: out of memory\n");
               return(NULL);
           }
       } else
           ret = target;
       in = str;
       out = ret;
       while(len >= 0) {
           if (*in == '%') {
               in++;
               if ((*in >= '0') && (*in <= '9')) 
                   *out = (*in - '0');
               else if ((*in >= 'a') && (*in <= 'f'))
                   *out = (*in - 'a') + 10;
               else if ((*in >= 'A') && (*in <= 'F'))
                   *out = (*in - 'A') + 10;
               in++;
               if ((*in >= '0') && (*in <= '9')) 
                   *out = *out * 16 + (*in - '0');
               else if ((*in >= 'a') && (*in <= 'f'))
                   *out = *out * 16 + (*in - 'a') + 10;
               else if ((*in >= 'A') && (*in <= 'F'))
                   *out = *out * 16 + (*in - 'A') + 10;
               in++;
               len -= 3;
           } else {
               *out++ = *in++;
               len--;
           }
       }
       *out = 0;
       return(ret);
   }
   
       uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |  
                       "&" | "=" | "+" | "$" | ","  
   
       pchar         = unreserved | escaped |  /**
                       ":" | "@" | "&" | "=" | "+" | "$" | ","   * xmlParseURIFragment:
       escaped       = "%" hex hex   * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    *
    * Parse an URI fragment string and fills in the appropriate fields
    * of the @uri structure.
    * 
    * fragment = *uric
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIFragment(xmlURIPtr uri, const char **str) {
       const char *cur = *str;
   
       if (str == NULL) return(-1);
   
       while (IS_URIC(cur)) NEXT(cur);
       if (uri != NULL) {
           if (uri->fragment != NULL) xmlFree(uri->fragment);
           uri->fragment = xmlURIUnescape(*str, cur - *str, NULL);
       }
       *str = cur;
       return(0);
   }
   
   /**
    * xmlParseURIScheme:
    * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    *
    * Parse an URI scheme
    * 
    * scheme = alpha *( alpha | digit | "+" | "-" | "." )
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIScheme(xmlURIPtr uri, const char **str) {
       const char *cur;
   
       if (str == NULL)
           return(-1);
       
       cur = *str;
       if (!IS_ALPHA(*cur))
           return(2);
       cur++;
       while (IS_SCHEME(*cur)) cur++;
       if (uri != NULL) {
           if (uri->scheme != NULL) xmlFree(uri->scheme);
           uri->scheme = xmlURIUnescape(*str, cur - *str, NULL); /* !!! strndup */
       }
       *str = cur;
       return(0);
   }
   
   /**
    * xmlParseURIOpaquePart:
    * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    *
    * Parse an URI opaque part
    * 
    * opaque_part = uric_no_slash *uric
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIOpaquePart(xmlURIPtr uri, const char **str) {
       const char *cur;
   
       if (str == NULL)
           return(-1);
       
       cur = *str;
       if (!IS_URIC_NO_SLASH(cur)) {
           return(3);
       }
       NEXT(cur);
       while (IS_URIC(cur)) NEXT(cur);
       if (uri != NULL) {
           if (uri->scheme != NULL) xmlFree(uri->scheme);
           uri->scheme = xmlURIUnescape(*str, cur - *str, NULL);
       }
       *str = cur;
       return(0);
   }
   
   /**
    * xmlParseURIPathSegments:
    * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    * @slash:  should we add a leading slash
    *
    * Parse an URI set of path segments
    * 
    * path_segments = segment *( "/" segment )
    * segment       = *pchar *( ";" param )
    * param         = *pchar
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash) {
       int ret;
       const char *cur;
   
       if (str == NULL)
           return(-1);
       
       cur = *str;
   
       do {
           while (IS_PCHAR(cur)) NEXT(cur);
           if (*cur == ';') {
               cur++;
               while (IS_PCHAR(cur)) NEXT(cur);
           }
           if (*cur != '/') break;
           cur++;
       } while (1);
       if (uri != NULL) {
           int len;
   
           /*
            * Concat the set of path segments to the current path
            */
           if (uri->path != NULL) {
           }
       }
       *str = cur;
       return(0);
   }
   
   /**
    * xmlParseURIHierPart:
    * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    *
    * Parse an URI hirarchical part
    * 
    * hier_part = ( net_path | abs_path ) [ "?" query ]
    * abs_path = "/"  path_segments
    * net_path = "//" authority [ abs_path ]
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIHierPart(xmlURIPtr uri, const char **str) {
       int ret;
       const char *cur;
   
       if (str == NULL)
           return(-1);
       
       cur = *str;
   
       if ((cur[0] == '/') && (cur[1] == '/')) {
           cur += 2;
           ret = xmlParseURIAuthority(uri, &cur);
           if (ret != NULL)
               return(ret);
           if (cur[0] == '/') {
               cur++;
               ret = xmlParseURIPathSegments(uri, &cur, 1);
           }
       } else if (cur[0] == '/') {
           cur++;
           ret = xmlParseURIPathSegments(uri, &cur, 1);
       } else {
           return(4);
       }
       if (ret != 0)
           return(ret);
       if (*cur == '?') {
           cur++;
           ret = xmlParseURIQuery(uri, &cur);
           if (ret != 0)
               return(ret);
       }
       *str = cur;
       return(0);
   }
   
   /**
    * xmlParseAbsoluteURI:
    * @uri:  pointer to an URI structure
    * @str:  pointer to the string to analyze
    *
    * Parse an URI reference string and fills in the appropriate fields
    * of the @uri structure
    * 
    * absoluteURI   = scheme ":" ( hier_part | opaque_part )
    *
    * Returns 0 or the error code
    */
   int
   xmlParseAbsoluteURI(xmlURIPtr uri, const char **str) {
       int ret;
   
       if (str == NULL)
           return(-1);
       
       ret = xmlParseURIScheme(uri, str);
       if (ret != 0) return(ret);
       if (**str != ':')
           return(1);
       (*str)++;
       if (**str == '/')
           return(xmlParseURIHierPart(uri, str));
       return(xmlParseURIOpaquePart(uri, str));
   }
   
   /**
    * xmlParseURIReference:
    * @uri:  pointer to an URI structure
    * @str:  the string to analyze
    *
    * Parse an URI reference string and fills in the appropriate fields
    * of the @uri structure
    * 
    * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
    *
    * Returns 0 or the error code
    */
   int
   xmlParseURIReference(xmlURIPtr uri, const char *str) {
       int ret;
       const char *tmp = str;
   
       if (str == NULL)
           return(-1);
       xmlCleanURI(uri);
   
       /*
        * Try first to parse aboslute refs, then fallback to relative if
        * it fails.
      */       */
       ret = xmlParseAbsoluteURI(uri, &str);
       if (ret != 0) {
           xmlCleanURI(uri);
           str = tmp;
           ret = xmlParseRelativeURI(uri, str);
       }
       if (ret != 0) {
           xmlCleanURI(uri);
           return(ret);
       }
   
       if (*str == '#') {
           str++;
           ret = xmlParseURIFragment(uri, &str);
           if (ret != 0) return(ret);
       }
       if (*str != 0) {
           xmlCleanURI(uri);
           return(1);
       }
       return(0);
   }
   
 /**  /**
  * xmlBuildURI:   * xmlBuildURI:
  * @URI:  the URI instance found in the document   * @URI:  the URI instance found in the document
  * @doc:  the document itself   * @base:  the base value
  * @node:  the node carrying the instance (optionnal)  
  *   *
  * Computes he final URI of the reference done by checking that   * Computes he final URI of the reference done by checking that
  * the given URI is valid, and getting the base and building the   * the given URI is valid, and building the final URI using the
  * final URI if needed   * base URI.
  *   *
  * Returns a new URI string (to be freed by the caller)   * Returns a new URI string (to be freed by the caller)
  */   */
 xmlChar *  xmlChar *
 xmlBuildURI(const xmlChar *URI, xmlDocPtr doc, xmlNodePtr node) {  xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
     /* TODO */      /* TODO */
     return(NULL);      return(NULL);
 }  }

Removed from v.1.3  
changed lines
  Added in v.1.4


Webmaster