home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / text / hyper / hsc_source.lha / hsc / source / hsclib / uri.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-08  |  11.8 KB  |  453 lines

  1. /*
  2.  * uri.c
  3.  *
  4.  * functions for uri parsing of tag arguments
  5.  *
  6.  * Copyright (C) 1995,96  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated:  8-Dec-1996
  23.  * created: 16-Jul-1995
  24.  */
  25.  
  26. #define NOEXTERN_HSCLIB_URI_H
  27.  
  28. #include "ugly/fname.h"
  29.  
  30. #include "hsclib/inc_base.h"
  31. #include "hsclib/idref.h"
  32. #include "hscprj/project.h"
  33. #include "hsclib/uri.h"
  34.  
  35. #define PARENT_URI "../"        /* string for parent dir within URIs */
  36.  
  37. /*
  38.  * conv_path2uri
  39.  *
  40.  * convert a path for local (system-dependant)
  41.  * file system to URI
  42.  */
  43. VOID conv_path2uri(EXPSTR * dest, STRPTR path)
  44. {
  45.     clr_estr(dest);
  46.  
  47. #ifdef AMIGA
  48.     /* replace leading parent directories by "../" */
  49.     while (!strncmp(path, PARENT_DIR, strlen(PARENT_DIR)))
  50.     {
  51.         app_estr(dest, PARENT_URI);
  52.         path += strlen(PARENT_DIR);
  53.     }
  54.  
  55.     while (path[0])
  56.     {
  57.         /* replace all "//" by "../" */
  58.         if ((path[0] == '/') && (path[1] == '/'))
  59.         {
  60.             app_estr(dest, PARENT_URI);
  61.             path += 2;
  62.         }
  63.         else
  64.         {
  65.             app_estrch(dest, path[0]);
  66.             path++;
  67.         }
  68.     }
  69.  
  70. #elif defined MSDOS
  71.     /* replace "\" by "/" */
  72.     while (path[0])
  73.     {
  74.         if ((path[0] == '\\'))
  75.             app_estrch(dest, '/');
  76.         else
  77.             app_estrch(dest, path[0]);
  78.         path++;
  79.     }
  80.  
  81. #elif defined UNIX
  82.     /* simply copy path */
  83.     set_estr(dest, path);
  84. #else
  85. #error "system not supported: conv_path2uri"
  86. #endif
  87. }
  88.  
  89. /*
  90.  * conv_uri2path
  91.  *
  92.  * convert a uri to a path for local (system-dependant)
  93.  * file system
  94.  */
  95. VOID conv_uri2path(EXPSTR * dest, STRPTR uri, BOOL weenix)
  96. {
  97.     clr_estr(dest);
  98.  
  99. #ifdef AMIGA
  100.     if (weenix)
  101.     {
  102.         /* convert leading "/" to ":" */
  103.         /* convert leading "~" to ":" */
  104.         if (!strncmp(uri, "/", 1)
  105.             || !strncmp(uri, "~/", 2)
  106.             || !strncmp(uri, "~", 1))
  107.         {
  108.             app_estr(dest, ":");
  109.             uri++;
  110.         }
  111.     }
  112.  
  113.     /* convert leading "../" to "/" */
  114.     while (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  115.     {
  116.         app_estr(dest, PARENT_DIR);
  117.         uri += strlen(PARENT_URI);
  118.     }
  119.  
  120.     /* convert inside "../" to "//" */
  121.     while (uri[0])
  122.     {
  123.         if (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  124.         {
  125.             app_estrch(dest, '/');
  126.             uri += strlen(PARENT_URI);
  127.         }
  128.         else
  129.         {
  130.             app_estrch(dest, uri[0]);
  131.             uri++;
  132.         }
  133.     }
  134.  
  135. #elif defined MSDOS
  136.     /* replace "\" by "/" */
  137.     while (uri[0])
  138.     {
  139.         if (uri[0] == '/')
  140.             app_estrch(dest, '\\');
  141.         else
  142.             app_estrch(dest, uri[0]);
  143.         uri++;
  144.     }
  145.  
  146. #elif defined UNIX
  147.     set_estr(dest, uri);
  148. #else
  149. #error "system not supported: conv_uri2path"
  150. #endif
  151. }
  152.  
  153. /*
  154.  * uri_kind
  155.  *
  156.  * evaluate kind of uri
  157.  */
  158. URIKIND uri_kind(STRPTR uri)
  159. {
  160.     URIKIND kind = URI_abs;
  161.  
  162.     if (upstrncmp(uri, ABSURI_ID, strlen(ABSURI_ID)))
  163.     {
  164.         if (uri[0] == '/')
  165.             kind = URI_relserv;
  166.         else
  167.         {
  168.             STRPTR colon_pos = strchr(uri, ':');
  169.             STRPTR slash_pos = strchr(uri, '/');
  170.  
  171.             if (colon_pos)
  172.                 if (slash_pos)
  173.                     if (colon_pos < slash_pos)
  174.                         kind = URI_ext;
  175.                     else
  176.                         kind = URI_rel;
  177.                 else
  178.                     kind = URI_ext;
  179.             else
  180.                 kind = URI_rel;
  181.         }
  182.     }
  183.     return (kind);
  184. }
  185.  
  186. /*
  187.  * convert uri to filename in destination-dir
  188.  */
  189. static VOID conv_hscuri2fileNuri(HSCPRC * hp, EXPSTR * dest_uri, EXPSTR * dest_fname, STRPTR uri)
  190. {
  191.     EXPSTR *rel_path = init_estr(32);   /* relative path */
  192.     URIKIND kind = uri_kind(uri);
  193.  
  194.     clr_estr(dest_uri);
  195.     clr_estr(dest_fname);
  196.  
  197.     /* if a <BASE HREF=".."> was found before,
  198.      * therefor treat URI as absolute
  199.      */
  200.     if (hp->docbase_set)
  201.         kind = URI_ext;
  202.  
  203.     /* evaluate kind of URI */
  204.     if (kind == URI_abs)
  205.         uri++;                  /* skip ":" */
  206.  
  207.     /* reset destination filename */
  208.     set_estr(dest_fname, "");
  209.  
  210.     if (kind == URI_abs)
  211.     {
  212.         /*
  213.          * parse absolute uri
  214.          */
  215.         D(fprintf(stderr, DHL "exists `%s' [abs]\n", uri));
  216.  
  217.         /* check if local uri exists */
  218.         {
  219.             EXPSTR *dest_relfname = init_estr(32);
  220.             conv_uri2path(dest_relfname, uri, hp->weenix);
  221.  
  222.             estrcpy(dest_fname, hp->destdir);
  223.             estrcat(dest_fname, dest_relfname);
  224.  
  225.             del_estr(dest_relfname);
  226.         }
  227.  
  228.         D(fprintf(stderr, DHL "  -> file `%s'\n",
  229.                   estr2str(dest_fname)));
  230.  
  231.         /* create path of destination file */
  232.         estrcpy(dest_uri, hp->reldir);
  233.         app_estr(dest_uri, uri);
  234.  
  235.         get_relfname(rel_path, uri, estr2str(hp->reldir));
  236.         D(fprintf(stderr, DHL "  -> rel. path `%s' (`%s')\n",
  237.                   estr2str(rel_path),
  238.                   estr2str(hp->reldir)));
  239.  
  240.         /* debug */
  241.         D(fprintf(stderr, DHL "  -> real path `%s'\n", uri));
  242.  
  243.         /* convert (filesystem depending) path to uri */
  244.         conv_path2uri(dest_uri, estr2str(rel_path));
  245.  
  246.         /* debug */
  247.         D(fprintf(stderr, DHL "  -> real uri  `%s'\n",
  248.                   estr2str(dest_uri)));
  249.     }
  250.     else if (kind == URI_rel)
  251.     {
  252.         /*
  253.          * parse relative uri
  254.          */
  255.         EXPSTR *uri_path = init_estr(32);
  256.  
  257.         /* debug */
  258.         D(fprintf(stderr, DHL "exists `%s' [rel]\n", uri));
  259.  
  260.         /* create local filename */
  261.         conv_uri2path(uri_path, uri, hp->weenix);
  262.         estrcat(dest_fname, hp->destdir);
  263.         estrcat(dest_fname, hp->reldir);
  264.         estrcat(dest_fname, uri_path);
  265.  
  266.         /* create uri (only copy path) */
  267.         set_estr(dest_uri, uri);
  268.  
  269.         /* debug */
  270.         D(
  271.              {
  272.              fprintf(stderr, DHL "  -> real path `%s'\n",
  273.                      estr2str(dest_fname));
  274.              fprintf(stderr, DHL "  -> real uri  `%s'\n",
  275.                      estr2str(dest_uri));
  276.              }
  277.         );
  278.  
  279.         del_estr(uri_path);
  280.     }
  281.     else
  282.     {
  283. #if 0
  284.         STRARR tmp[300];
  285.  
  286.         strcpy(tmp, "unknown uri-kind: ");
  287.         strcat(tmp, uri);
  288.         panic(tmp);
  289. #endif
  290.         set_estr(dest_uri, uri);
  291.         set_estr(dest_fname, "");
  292.     }
  293.  
  294.     /* free resources */
  295.     del_estr(rel_path);
  296. }
  297.  
  298. VOID conv_hscuri2file(HSCPRC * hp, EXPSTR * dest_fname, STRPTR uri)
  299. {
  300.     EXPSTR *dest_uri = init_estr(64);
  301.     conv_hscuri2fileNuri(hp, dest_uri, dest_fname, uri);
  302.     del_estr(dest_uri);
  303. }
  304.  
  305. /*
  306.  * parse_uri
  307.  *
  308.  * check uri-string for syntatic correctnes;
  309.  * if the uri refers to an local file, convert its absolute
  310.  * path to a relative path and check its existence.
  311.  *
  312.  * uri = "rsrc_type://host.domain:port/pathname#id"
  313.  */
  314. VOID parse_uri(HSCPRC * hp, EXPSTR * dest_uri, STRPTR uri)
  315. {
  316.     STRPTR host = NULL;
  317.     STRPTR port = NULL;
  318.     STRPTR path = NULL;
  319.     STRPTR name = NULL;
  320.  
  321.     clr_estr(dest_uri);
  322.  
  323.     if (uri)
  324.     {
  325.         /* check for valid uri */
  326.         URIKIND kind = uri_kind(uri);
  327.         if ((kind == URI_ext) || (kind == URI_relserv))
  328.         {
  329.             if (kind == URI_ext)
  330.             {
  331.                 /*
  332.                  * check global uri
  333.                  */
  334.                 if (!host)
  335.                     host = "";
  336.                 if (!port)
  337.                     port = "";
  338.                 if (!host)
  339.                     host = "";
  340.  
  341.                 /*
  342.                  * TODO: parse global uris
  343.                  */
  344.             }
  345.             set_estr(dest_uri, uri);
  346.         }
  347.         else
  348.         {
  349.             /*
  350.              * check local uri
  351.              */
  352.  
  353.             /* destination file name that's existence is checked if
  354.              * chkuri is enabled */
  355.             EXPSTR *dest_fname = init_estr(32);
  356.             STRPTR noabsuri = uri;
  357.  
  358.             /* evaluate kind of URI */
  359.             if (kind == URI_abs)
  360.                 noabsuri++;     /* skip ":" */
  361.  
  362.             /* extract path and #name */
  363.             if (noabsuri[0] == '#')
  364.             {
  365.                 path = NULL;
  366.                 name = noabsuri + 1;    /* skip '#' for ":#id" */
  367.             }
  368.             else
  369.             {
  370.                 path = strtok(uri, "#");
  371.                 name = strtok(NULL, "");
  372.             }
  373.  
  374.             if (path)
  375.             {
  376.                 FILE *exist = NULL;
  377.  
  378.                 /*
  379.                  * check existence of local uri
  380.                  */
  381.                 conv_hscuri2fileNuri(hp, dest_uri, dest_fname, path);
  382.                 if (hp->chkuri
  383.                     && !(hsc_get_msg_ignore(hp, MSG_NO_URIPATH)))
  384.                 {
  385.                     exist = fopen(estr2str(dest_fname), "r");
  386.                     if (!exist)
  387.                     {
  388.                         hsc_msg_nouri(hp, estr2str(dest_fname), uri, NULL);
  389.                     }
  390.                     else
  391.                     {
  392.                         fclose(exist);
  393.  
  394.                         /* check id */
  395.                         if (hp->chkid && name)
  396.                         {
  397.                             STRPTR doc_fname = estr2str(dest_fname);
  398.  
  399.                             if (!fnamecmp(hp->project->document->docname,
  400.                                           doc_fname))
  401.                             {
  402.                                 /* filename references current document */
  403.                                 add_local_idref(hp, name);
  404.                             }
  405.                             else
  406.                             {
  407.                                 /* filename reference other document;
  408.                                  * lookup project-data */
  409.                                 switch (check_document_id(hp->project,
  410.                                                           doc_fname, name))
  411.                                 {
  412.                                 case ERR_CDI_OK:
  413.                                     D(fprintf(stderr, DHL "  id ok\n"));
  414.                                     break;
  415.                                 case ERR_CDI_NoID:
  416.                                     hsc_msg_unknown_id(hp, NULL, name);
  417.                                     break;
  418.                                 case ERR_CDI_NoDocumentEntry:
  419.                                     hsc_message(hp, MSG_NO_DOCENTRY,
  420.                                                 "no entry for document %q "
  421.                                               "in project data to check %i",
  422.                                                 estr2str(dest_fname),
  423.                                                 name);
  424.                                     break;
  425.                                 default:
  426.                                     panic("unknown returncode");
  427.                                     break;
  428.                                 }
  429.                             }
  430.                         }
  431.                     }
  432.                 }
  433.             }
  434.             else
  435.             {
  436.                 /* check existence ID referencing into current file */
  437.                 if (hp->chkid && name)
  438.                     add_local_idref(hp, name);
  439.             }
  440.  
  441.             /* add #name part */
  442.             if (name)
  443.             {
  444.                 app_estrch(dest_uri, '#');
  445.                 app_estr(dest_uri, name);
  446.             }
  447.             /* free resources */
  448.             del_estr(dest_fname);
  449.         }                       /* else (rsrc) */
  450.     }                           /* if (uri) */
  451. }
  452.  
  453.