riscosify changes

Alex Waugh alex at alexwaugh.com
Fri Dec 27 09:28:15 PST 2002


Some more riscosify changes:

"./foo.c" now translates to "@.c.foo" rather than "c.foo"
Better handling of . and .. at beginning and ends of filenames, and
things like "./.."
Removes ,xyz when the filename is just a leafname.
Interprets things like ".svn/text-base/malloc.c.svn-base" as unix format
not RISC OS format.
It includes my patch of 24 Nov, which appears to have got lost.
Also attached is a regression test which can be placed in
unixlib/source/test

Alex

-- 
Alex Waugh                                           alex at alexwaugh.com

PHP, Roots, Subversion, WebJames and more from http://www.alexwaugh.com/
-------------- next part --------------
/*
Regression tests for riscosify

Before running:
*unset UnixFS$/tmp
*set UnixEnv$testriscosify$sfix c:o:h:cc:s:cpp
*set UnixFS$/xxx xxx

*/


#include <stdio.h>
#include <string.h>
#include <unixlib/local.h>

char tests[][2][256] = {
{"/tmp","<Wimp$ScrapDir>"},
{"/tmp/file","<Wimp$ScrapDir>.file"},
{"/tmp/file.c","<Wimp$ScrapDir>.c.file"},
{"/usr/xxx/fred.c","xxx.c.fred"},
{"/xxx/fred.php","xxx.fred/php"},
{"$.work.!unixlib","$.work.!unixlib"},
{"$/work/!unixlib","$.work.!unixlib"},
{"%/cc1,ffb","%.cc1"},
{"%/cc1.o","%.o.cc1"},
{"%/cc1.o,ffb","%.o.cc1"},
{"%.cc1","%.cc1"},
{"^.fred/c","^.fred/c"},
{"<GCC$dir>.cc.smart","<GCC$dir>.cc.smart"},
{"<GCC$Dir>/cc.smart","<GCC$Dir>.cc/smart"},
{"<GCC$Dir>/smart.cc","<GCC$Dir>.cc.smart"},
{"<GCC$Dir>.cc.smart","<GCC$Dir>.cc.smart"},
{"<GCC$Dir>.config","<GCC$Dir>.config"},
{"./././c.cool","@.c/cool"},
{"../../../c.cool","^.^.^.c/cool"},
{"../cool.c","^.c.cool"},
{"././/./c.cool","@.c/cool"},
{"../../../c.cool","^.^.^.c/cool"},
{"../cool.c","^.c.cool"},
{"../cool.php","^.cool/php"},
{".plan","/plan"},
{"..cunningplan","//cunningplan"},
{"/idefs::4/$/fred/preset/s","idefs::4.$.fred.preset.s"},
{"/idefs::4/$/fred/preset.s","idefs::4.$.fred.s.preset"},
{"/rname.c","$.c.rname"},
{"/arm/rname.c","$.arm.c.rname"},
{"/arm//rname.c","$.arm.c.rname"},
{"//arm/rname.c","$.arm.c.rname"},
{"/arm/./rname.c","$.arm.c.rname"},
{"/<GCC$Dir>/config","<GCC$Dir>.config"},
{"/dev/tty","tty:"},
{"idefs::4.$.fred","idefs::4.$.fred"},
{"idefs::4/$/fred","idefs::4.$.fred"},
{"fred.c","c.fred"},
{"foo/fred.c","foo.c.fred"},
{"foo/fred.php","foo.fred/php"},
{"c/fred","c.fred"},
{"c.fred","c.fred"},
{"/gcc:/libgcc.o","gcc:o.libgcc"},
{"/gcc:libgcc.o","gcc:o.libgcc"},
{"gcc:/getopt.c","gcc:c.getopt"},
{"gcc:/o.libgcc","gcc:o/libgcc"},
{"gcc:c.getopt","gcc:c.getopt"},
{"gcc:c/getopt","gcc:c.getopt"},
{"gcc:getopt.c","gcc:c.getopt"},
{"gcc:foo/getopt.c","gcc:foo.c.getopt"},
{"gcc:foo.getopt/php","gcc:foo.getopt/php"},
{"gcc:getopt.php","gcc:getopt.php"},
{"gcc:getopt/php","gcc:getopt/php"},
{"gcc:foo/getopt","gcc:foo/getopt"},
{"foo.bar.o.getopt","foo.bar.o.getopt"},
{"foo/bar/o/getopt","foo.bar.o.getopt"},
{"/gccpkg:lib/gcc-lib/arm-riscos-aof/2_95_4/include/time.h","gccpkg:lib.gcc-lib.arm-riscos-aof.2_95_4.include.h.time"},
{"/gccpkg:include/unixlib/stddef.h","gccpkg:include.unixlib.h.stddef"},
{"idefs::4.$.fred.s.preset","idefs::4.$.fred.s.preset"},
{"idefs::4.$.fred.preset.s","idefs::4.$.fred.preset.s"},
{"idefs::4/$/fred/preset.s","idefs::4.$.fred.s.preset"},
{"Devices#baud9600:serial","Devices#baud9600:serial"},
{"LanMan98#notypes::mint.$.index/php","LanMan98#notypes::mint.$.index/php"},
{"LanMan98#no.types::mint/$/index.php","LanMan98#no.types::mint.$.index/php"},
{"/LanMan98#no/types::mint/$/index.php","LanMan98#no/types::mint.$.index/php"},
{"c/jimmyhill","c.jimmyhill"},
{"fred/preset.s","fred.s.preset"},
{"getopt.c","c.getopt"},
{"cc.smart","cc.smart"},
{"php.smart","php/smart"},
{"smart.cc","cc.smart"},
{"gcc-2.7.2.2.tar.gz","gcc-2/7/2/2/tar/gz"},
{"foo/fred.c.text-base","foo.fred/c/text-base"},
{"foo.o.bar","foo.o.bar"},
{":4.$.something",":4.$.something"},
{".","@"},
{"..","^"},
{"gcc:/./o.libgcc","gcc:o/libgcc"},
{"gcc:/../o.libgcc","gcc:^.o/libgcc"},
{"gcc:/../libgcc.o","gcc:^.o.libgcc"},
{"gcc:^.o.libgcc","gcc:^.o.libgcc"},
{"a","a"},
{"abba","abba"},
{"Makefile,fe1","Makefile"},
{"./.","@"},
{"../.","^"},
{"./..","@.^"},
{"./foo/..","@.foo.^"},
{"foo/..","@"},
{"foo/.","foo"},
{"./foo/.","@.foo"},
{"./foo.c","@.c.foo"},
{"foo/","foo"},
{"foo//","foo"},
{"","@"}};

int main (void)
{
	char buffer[256];
	int i;
	int j;
	int fail = 0;

	i = -1;
	do {
		i++;
		printf("Testing %s\n",tests[i][0]);
		__riscosify(tests[i][0], 0 ,0 | __RISCOSIFY_FILETYPE_EXT | __RISCOSIFY_DONT_CHECK_DIR, buffer, 256, NULL);

		fail = strcmp(buffer,tests[i][1]);
		printf("%s\n",buffer);
		for (j=0;j<60;j++) printf(" ");
		printf("%s\n", fail ? "FAIL" : "Pass");
	} while (tests[i][0][0] && !fail);

	return 0;
}


-------------- next part --------------
Index: unixlib/source/common/riscosify.c
===================================================================
RCS file: /usr/local/cvsroot/gccsdk/unixlib/source/common/riscosify.c,v
retrieving revision 1.6
diff -u -r1.6 riscosify.c
--- unixlib/source/common/riscosify.c	15 Dec 2002 13:35:44 -0000	1.6
+++ unixlib/source/common/riscosify.c	27 Dec 2002 16:42:22 -0000
@@ -295,14 +295,16 @@
 static char *
 translate_or_null (int create_dir, int flags,
                    char *buffer, const char *buf_end, int *filetype,
-                   char *out, const char *in)
+                   char *out, const char *in, int path)
 {
   /* in points to a (possibly partial) unix pathname.
      If it was absolute, it will have had any leading '/'s stripped, and any
      RISC OS specific parts will already have been copied */
 
+  const char *start = in;      /* The start of our input */
   const char *last_slash = in; /* The next character after the last '/'
                                   discovered in the input */
+  const char *previous_slash = NULL; /* The previous value of last_slash */
   char *last_out_slash = out;  /* The position in the output that corresponds
                                   to last_slash in the input */
   const char *last_dot = NULL; /* The last '.' found in the input */
@@ -330,10 +332,32 @@
         case '.':
           if (in[1] == '/')
             {
-              /* Skip any ./ */
+              /* Skip any ./
+                 If it is at the beginning the output a @. */
+
+              if (in == start && !path)
+               {
+                 if (out + 2 > buf_end)
+                   return NULL;
+
+                 *out++ = '@';
+                 *out++ = '.';
+
+                 last_slash = in + 1;
+                 last_out_slash = out;
+
+               }
+
               in += 2;
               last_slash = in;
             }
+          else if (in > start && in[-1] == '/' && in[1] == '\0')
+            {
+              /* Skip any /. at the end of a filename
+                 The check against start ensures we don't read earlier
+                 than the start of the input buffer */
+              in++;
+            }
           else if (in[1] == '.' && in[2] == '/')
             {
               /* Change ../ to ^. */
@@ -347,6 +371,34 @@
               *out++ = '.';
               last_out_slash = out;
             }
+          else if (in > start && in[-1] == '/' && in[1] == '.' && in[2] == '\0')
+            {
+              /* Change .. to ^ when at the end of a filename
+                 The check against start ensures we don't read earlier
+                 than the start of the input buffer */
+
+              in += 2;
+
+              if (previous_slash == start)
+                {
+                  /* Make a special case for foo/.. as RISC OS will canonicalise
+                     this to an empty string, and then complain about the lack
+                     of filename */
+
+                  out = buffer;
+                  *out++ = '@';
+                  *out = '\0';
+
+                }
+              else
+                {
+
+                  if (out + 1 > buf_end)
+                    return NULL;
+
+                  *out++ = '^';
+                }
+            }
           else
             {
               /* Just a . as part of a filename */
@@ -365,10 +417,13 @@
           while (in[1] == '/')
             in++;
 
+          previous_slash = last_slash;
+
           last_slash = ++in;
 
-          /* Copy as a '.', unless nothing else has been output yet */
-          if (out != buffer)
+          /* Copy as a '.', unless nothing else has been output yet or there
+             is already a . */
+          if (out > buffer && out[-1] != '.')
             *out++ = '.';
 
           last_out_slash = out;
@@ -388,11 +443,18 @@
         }
     }
 
-  /* If the input ended in /. then remove it.
-     gcc uses filenames like this to ensure the resulting path will be a
-     directory even if the given path is a symbolic link.  */
-  if (out > buffer + 2 && out[-1] == '/' && out[-2] == '.')
-    out -= 2;
+  /* If the input ended in any / then remove them. */
+  while (out > buffer + 1 && out[-1] == '.')
+    out--;
+
+  if (out == buffer && !path)
+    {
+      /* Translate an empty filename into the current dir */
+      if (out +1 > buf_end)
+        return NULL;
+
+      *out++ = '@';
+    }
 
 #ifdef DEBUG
   *out = '\0';
@@ -505,6 +567,12 @@
   /* Terminate the output */
   *out = '\0';
 
+#ifdef DEBUG
+  __os_print ("final output '");
+  __os_print (buffer);
+  __os_print ("'\r\n");
+#endif
+
   return out;
 }
 
@@ -520,9 +588,11 @@
                int *filetype, char *out, const char *in, const char *name,
                int path)
 {
-  const char *last;
+  char *last;
+  char *penultimate;
   const char *orig_in = name;
   char *orig_out = buffer;
+  char *slash = NULL;
 
 #ifdef DEBUG
   __os_print ("-- guess_or_null:\r\n");
@@ -541,9 +611,23 @@
       orig_in = in;
     }
 
-  /* Find the first dir separator */
-  while (*in && *in != '.' && *in != '/')
+  /* Find the last two dots or slashes */
+  last = NULL;
+  penultimate = NULL;
+  while (*in)
     {
+      if (*in == '.')
+        {
+          penultimate = last;
+          last = out;
+        }
+      else if (*in == '/')
+        {
+          penultimate = last;
+          last = out;
+          slash = out;
+        }
+
       *out++ = *in++;
 
       if (out > buf_end)
@@ -552,48 +636,46 @@
 
   *out = '\0';
 
-  if (*in == '\0')
+  if (last == NULL)
     {
-      /* Just a leafname, and we've already copied it all */
-      return out;
+      /* Just a leafname, so let translate_or_null deal with ,xyz etc. */
+      return translate_or_null (create_dir, flags, buffer, buf_end,
+                                filetype, orig_out, orig_in, path);
     }
 
-  if (__sfixfind (orig_out))
+  if (penultimate == NULL)
+    penultimate = orig_out - 1;
+
+  if (*last == '.')
     {
-      /* The first segment is a known suffix */
-      if (*in == '.')
+      *last = '\0';
+
+      if (slash == NULL && __sfixfind (penultimate + 1))
         {
-          /* c.getopt so it's probably RISC OS */
-          return copy_or_null (out, in, buf_end);
+          /* foo.c.getopt so it's probably RISC OS, unless there was
+             a slash earlier in the input */
+          return copy_or_null (orig_out, orig_in, buf_end);
         }
-      else
+
+      if (__sfixfind (last + 1))
         {
-          /* c/getopt so it's probably unix */
-          return translate_or_null (create_dir, flags, buffer,
-                                    buf_end, filetype, orig_out, orig_in);
+          /* foo/getopt.c so it's probably unix */
+          return translate_or_null (create_dir, flags, buffer, buf_end,
+                                    filetype, orig_out, orig_in, path);
         }
     }
-
-  /* Find the last dot or slash */
-  last = in;
-  while (*in)
+  else
     {
-      if (*in == '.' || *in == '/')
-        last = in;
+      *last = '\0';
 
-      in++;
-    }
-
-  if (*last && __sfixfind (last + 1))
-    {
-      /* The last segment is a known suffix */
-      if (*last == '.')
+      if (__sfixfind (penultimate + 1))
         {
-          /* foo/getopt.c so it's probably unix */
-          return translate_or_null (create_dir, flags, buffer, buf_end,
-                                    filetype, orig_out, orig_in);
+          /* foo/c/getopt so it's probably unix */
+          return translate_or_null (create_dir, flags, buffer,
+                                    buf_end, filetype, orig_out, orig_in, path);
         }
-      else
+
+      if (__sfixfind (last + 1))
         {
           /* foo.getopt/c so it's probably RISC OS */
           return copy_or_null (orig_out, orig_in, buf_end);
@@ -608,7 +690,7 @@
     return copy_or_null (orig_out, orig_in, buf_end);
 
   return translate_or_null (create_dir, flags, buffer, buf_end, filetype,
-                            orig_out, orig_in);
+                            orig_out, orig_in, path);
 }
 
 
@@ -657,7 +739,7 @@
 
   /* If the user has specified this flag, then we only need to copy
      the filename to the destination buffer.  */
-  if ((flags & __RISCOSIFY_NO_PROCESS) || *name == '\0')
+  if (flags & __RISCOSIFY_NO_PROCESS)
     return copy_or_null (buffer, name, buf_end);
 
   /* We can tell quite a lot from the first character of the path */
@@ -908,7 +990,7 @@
       /* By this point, all RISC OS specific parts have been copied across and
          all that remains is something like foo/bar/baz.c */
       return translate_or_null (create_dir, flags, buffer, buf_end, filetype,
-                                out, in);
+                                out, in, 1);
 
       break;
 
@@ -945,7 +1027,7 @@
             in++;
 
           return translate_or_null (create_dir, flags, buffer, buf_end,
-                                    filetype, out, in);
+                                    filetype, out, in, 1);
         }
       else
         {
@@ -991,7 +1073,7 @@
             in++;
 
           return translate_or_null (create_dir, flags, buffer, buf_end,
-                                    filetype, out, in);
+                                    filetype, out, in, 1);
         }
       else
         {
@@ -1003,13 +1085,15 @@
 
     case '.':
       /* RISC OS paths never start with a '.'
-         ./././c.cool      c.cool
-         ../../../c.cool   ^.^.^.c.cool
+         ./././c.cool      @.c/cool
+         ../../../c.cool   ^.^.^.c/cool
          ../cool.c         ^.c.cool
          .plan             /plan
          ..plan            //plan
          .                 @
-         ..                ^ */
+         ..                ^
+         ./.               @
+         ./..              @.^ */
 
       if (in[1] == '\0')
         {
@@ -1034,7 +1118,7 @@
         }
 
       return translate_or_null (create_dir, flags, buffer, buf_end, filetype,
-                                out, in);
+                                out, in, 0);
 
       break;
 
@@ -1124,7 +1208,7 @@
                     in++;
 
                   return translate_or_null (create_dir, flags, buffer, buf_end,
-                                            filetype, out, in);
+                                            filetype, out, in, 1);
                 }
               else
                 {
@@ -1142,7 +1226,7 @@
                     in++;
 
                   return translate_or_null (create_dir, flags, buffer, buf_end,
-                                            filetype, out, in);
+                                            filetype, out, in, 1);
                 }
               else
                 {


More information about the gcc mailing list