Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2. #include "muxps.h"
  3.  
  4. static inline int xps_tolower(int c)
  5. {
  6.         if (c >= 'A' && c <= 'Z')
  7.                 return c + 32;
  8.         return c;
  9. }
  10.  
  11. int
  12. xps_strcasecmp(char *a, char *b)
  13. {
  14.         while (xps_tolower(*a) == xps_tolower(*b))
  15.         {
  16.                 if (*a++ == 0)
  17.                         return 0;
  18.                 b++;
  19.         }
  20.         return xps_tolower(*a) - xps_tolower(*b);
  21. }
  22.  
  23. #define SEP(x)  ((x)=='/' || (x) == 0)
  24.  
  25. static char *
  26. xps_clean_path(char *name)
  27. {
  28.         char *p, *q, *dotdot;
  29.         int rooted;
  30.  
  31.         rooted = name[0] == '/';
  32.  
  33.         /*
  34.          * invariants:
  35.          *              p points at beginning of path element we're considering.
  36.          *              q points just past the last path element we wrote (no slash).
  37.          *              dotdot points just past the point where .. cannot backtrack
  38.          *                              any further (no slash).
  39.          */
  40.         p = q = dotdot = name + rooted;
  41.         while (*p)
  42.         {
  43.                 if(p[0] == '/') /* null element */
  44.                         p++;
  45.                 else if (p[0] == '.' && SEP(p[1]))
  46.                         p += 1; /* don't count the separator in case it is nul */
  47.                 else if (p[0] == '.' && p[1] == '.' && SEP(p[2]))
  48.                 {
  49.                         p += 2;
  50.                         if (q > dotdot) /* can backtrack */
  51.                         {
  52.                                 while(--q > dotdot && *q != '/')
  53.                                         ;
  54.                         }
  55.                         else if (!rooted) /* /.. is / but ./../ is .. */
  56.                         {
  57.                                 if (q != name)
  58.                                         *q++ = '/';
  59.                                 *q++ = '.';
  60.                                 *q++ = '.';
  61.                                 dotdot = q;
  62.                         }
  63.                 }
  64.                 else /* real path element */
  65.                 {
  66.                         if (q != name+rooted)
  67.                                 *q++ = '/';
  68.                         while ((*q = *p) != '/' && *q != 0)
  69.                                 p++, q++;
  70.                 }
  71.         }
  72.  
  73.         if (q == name) /* empty string is really "." */
  74.                 *q++ = '.';
  75.         *q = '\0';
  76.  
  77.         return name;
  78. }
  79.  
  80. void
  81. xps_absolute_path(char *output, char *base_uri, char *path, int output_size)
  82. {
  83.         if (path[0] == '/')
  84.         {
  85.                 fz_strlcpy(output, path, output_size);
  86.         }
  87.         else
  88.         {
  89.                 fz_strlcpy(output, base_uri, output_size);
  90.                 fz_strlcat(output, "/", output_size);
  91.                 fz_strlcat(output, path, output_size);
  92.         }
  93.         xps_clean_path(output);
  94. }
  95.