You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by dl...@apache.org on 2007/08/13 00:16:41 UTC

svn commit: r565176 - /harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c

Author: dlydick
Date: Sun Aug 12 15:16:40 2007
New Revision: 565176

URL: http://svn.apache.org/viewvc?view=rev&rev=565176
Log:
Renamed function to manifest_get_main_from_file()
and adjusted to work better at reading manifest
data from manifest file.

Added function manifest_get_main_from_bfr() to
read manifest data from a buffer, typically as
read from an archive into that buffer.  This is
the preferred approach for archives instead of
reading into a temporary file and calling the
other function.

Modified:
    harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c

Modified: harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c?view=diff&rev=565176&r1=565175&r2=565176
==============================================================================
--- harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c (original)
+++ harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/manifest.c Sun Aug 12 15:16:40 2007
@@ -51,12 +51,13 @@
 #include "util.h"
 
 /*!
- * @brief Search a JAR manifest file for a main class attribute.
+ * @name Search a JAR manifest file or buffer image for a main
+ * class attribute.
  *
  * This attribute MUST be all on one line and without any
  * line continuations breaking up the class name.  Look for
  * a line of text like this, where @b | indicates that the
- * following character is the first one on the line:
+ * following character is the first one on the line of text:
  *
  * @verbatim
       |
@@ -74,7 +75,7 @@
  *
  * @todo  HARMONY-6-jvm-manifest.c-1 Although such a continuation
  *        is supported by the JAR file, this implementation does
- *        not support it (yet).  With this restriction, the
+ *        not support it (yet).  With this restriction, then
  *        if only one single space separates the name of the
  *        attribute and the class name, then since a line may be
  *        up to 72 characters long (that is
@@ -83,17 +84,25 @@
  *        the class name may be 61 characters long.
  *
  *
- * @param  mnfname   JAR manifest file name, /absolute/path/name
- *         
+ * @returns Heap pointer to null-terminated startup class name.
+ *          Call HEAP_FREE_DATA() when done.  Returns
+ *          @link #rnull rnull@endlink if startup class
+ *          name was not found.
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Search a JAR manifest file
  *
- * @returns Heap pointer to null-terminated class name, or
- *          @link #rnull rnull@endlink if not found.
- *          Call HEAP_FREE_DATA() when done.
  *
+ * @param  mnfname   JAR manifest file name, /absolute/path/name
+ *         
  */
-rchar *manifest_get_main(rchar *mnfname)
+rchar *manifest_get_main_from_file(rchar *mnfname)
 {
-    ARCH_FUNCTION_NAME(manifest_get_main);
+    ARCH_FUNCTION_NAME(manifest_get_main_from_file);
 
     rvoid *mf;  /* Portability library does (FILE) part */
 
@@ -106,15 +115,18 @@
 
     rchar *mnfdata = HEAP_GET_DATA(JVMCFG_STDIO_BFR, rfalse);
 
-    int mclen =  portable_strlen(JVMCFG_JARFILE_MANIFEST_MAIN_CLASS);
+    rint mclen =  portable_strlen(JVMCFG_JARFILE_MANIFEST_MAIN_CLASS);
 
-    /* Read until end of file or match located */
+    /*
+     * Read until end of file or match located.
+     *  \n is at the end of each bfr
+     */
     while (mnfdata ==
            (rchar *) portable_fgets(mnfdata, JVMCFG_STDIO_BFR, mf))
     {
         /*
          * Scan for ^Main-Class: attribute name (text starting
-         * at beginnin of line)
+         * at beginning of line)
          */
         if (0 != portable_strncmp(mnfdata,
                                   JVMCFG_JARFILE_MANIFEST_MAIN_CLASS,
@@ -130,7 +142,8 @@
          * This will be the start of the class name.
          */
         rint i;
-        for (i = mclen; i < portable_strlen(mnfdata); i++)
+        rint mdlen = portable_strlen(mnfdata);
+        for (i = mclen; i < mdlen; i++)
         {
             /* if <b>white space</b> is rfalse */
             if (0 == portable_isspace((int) mnfdata[i]))
@@ -140,6 +153,12 @@
         }
         /* If nothing else, the \n at end of line is white space */
 
+        /* But if somehow last line has no \n then check end of bfr */
+        if (i == mdlen)
+        {
+            break;
+        }
+
         /*
          * Class name found.
          *
@@ -147,7 +166,7 @@
          * This will be the end of the class name.
          */
         rint j;
-        for (j = i; j < portable_strlen(mnfdata); j++)
+        for (j = i; j < mdlen; j++)
         {
             /* if <b>white space</b> is @link #rtrue rtrue@endlink */
             if (0 != portable_isspace((int) mnfdata[j]))
@@ -157,42 +176,135 @@
         }
         /* If nothing else, the \n at end of line is white space */
 
-        portable_fclose(mf);
+        /* But error if no class name */
+        if (j == i)
+        {
+            break;
+        }
 
         /* Allocate space for non-empty class name plus NUL byte */
-        rchar *mnfresult;
-        if (i != j)
-        { 
-            mnfresult = HEAP_GET_DATA(j - i + sizeof(rchar), rfalse);
-
-            /* If failure above, HEAP_FREE_DATA(mnfdata) is never run */
-        }
-        else
-        {
-            /* Do not process empty class name, declare error instead */
-            HEAP_FREE_DATA(mnfdata);
-
-            sysErrMsg(arch_function_name,
-                      "Missing class name in manifest file %s",
-                      mnfname);
-            exit_jvm(EXIT_MANIFEST_JAR);
-/*NOTREACHED*/
-        }
+        rchar *mnfresult = HEAP_GET_DATA(j - i + sizeof(rchar), rfalse);
 
         portable_memcpy(mnfresult, &mnfdata[i], j - i);
         mnfresult[j - i] = '\0';
 
+        portable_fclose(mf);
         HEAP_FREE_DATA(mnfdata);
         return(mnfresult);
     }
 
-    portable_fclose(mf);
 
+    /* Do not process empty class name, declare error instead */
+    portable_fclose(mf);
     HEAP_FREE_DATA(mnfdata);
 
     return((rchar *) rnull);
 
-} /* END of manifest_get_main() */
+} /* END of manifest_get_main_from_file() */
+
+
+/*!
+ * @brief Search a buffer containing a JAR manifest image
+ *
+ *
+ * It is @e assumed that the main class keyword is at the beginning of
+ * the line as described above due to the use of portable_strstr() .
+ * However, this is not checked.
+ *
+ * @todo  HARMONY-6-jvm-manifest.c-2 Check for the main class keyword
+ *        being found at the beginning of the line, either the first
+ *        character of the buffer or immediately following a newline.
+ *
+ * @warning Make <i>absolutely sure</i> that the final byte of the input
+ *          parameter @b mbfr is a @b NUL character for proper string
+ *          termination in
+ *          @link portable_strstr() portable_strstr()@endlink .
+ *          This will probably mean that the allocated buffer will have
+ *          either (a) an extra byte containing NUL, or (b) its last
+ *          byte will be converted from newline to NUL, or (c) append
+ *          a NUL byte to the manifest file buffer when it is extracted
+ *          from the Java archive.  The latter approach is actually
+ *          implemented, so no further action is needed by the caller.
+ *
+ * @param  mbfr    JAR manifest file contained in a buffer
+ *         
+ * @param  mbfrlen Length of JAR manifest file buffer in bytes
+ *         
+ */
+rchar *manifest_get_main_from_bfr(rchar *mbfr, rint mbfrlen)
+{
+    ARCH_FUNCTION_NAME(manifest_get_main_from_bfr);
+
+    rchar *mclocation =
+        portable_strstr(mbfr, JVMCFG_JARFILE_MANIFEST_MAIN_CLASS);
+
+    /* If bfr does not contain keyword, then cannot contain class name*/
+    if (rnull != mclocation)
+    {
+        return((rchar *) rnull);
+    }
+
+    rint mclen = portable_strlen(JVMCFG_JARFILE_MANIFEST_MAIN_CLASS);
+
+    rint mcoffset = (mclocation - mbfr) / sizeof(rchar);
+
+    /*
+     * Attribute name found.
+     *
+     * Scan for first non-white character after attribute name.
+     * This will be the start of the class name.
+     */
+    rint i;
+    for (i = mclen + mcoffset; i < mbfrlen; i++)
+    {
+        /* if <b>white space</b> is rfalse */
+        if (0 == portable_isspace((int) mbfr[i]))
+        {
+            break; /* Found first non-white-space character */
+        }
+    }
+    /* If nothing else, the \n at end of line is white space */
+
+    /* But if somehow last line has no \n then check end of bfr */
+    if (mbfrlen == i)
+    {
+        return((rchar *) rnull);
+    }
+
+    /*
+     * Class name found.
+     *
+     * Scan for first white character after class name.
+     * This will be the end of the class name.
+     */
+    rint j;
+    for (j = i; j < mbfrlen; j++)
+    {
+        /* if <b>white space</b> is @link #rtrue rtrue@endlink */
+        if (0 != portable_isspace((int) mbfr[j]))
+        {
+            break;  /* Found first white-space character */
+        }
+    }
+    /* If nothing else, the \n at end of line is white space */
+
+    /* But error if no class name */
+    if (i == j)
+    {
+        return((rchar *) rnull);
+    }
+
+    /* Allocate space for non-empty class name plus NUL byte */
+    rchar *mnfresult = HEAP_GET_DATA(j - i + sizeof(rchar), rfalse);
+
+    portable_memcpy(mnfresult, &mbfr[i], j - i);
+    mnfresult[j - i] = '\0';
+
+    return(mnfresult);
+
+} /* END of manifest_get_main_from_bfr() */
+
 
+/*@} */ /* End of grouped definitions */
 
 /* EOF */