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/12 23:09:11 UTC
svn commit: r565150 -
/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c
Author: dlydick
Date: Sun Aug 12 14:09:10 2007
New Revision: 565150
URL: http://svn.apache.org/viewvc?view=rev&rev=565150
Log:
Conditionally place 'tmparea' into CLASSPATH.
Demand absolute path names for Windows CLASSPATH entries.
Do not support relative paths: D:..\dir\name
Make classpath_isjar() more intelligent.
Comment out classpath_inner_class_adjust().
Have classpath_get_from_prchar() return (classpath_get_from_prchar).
It also calls jarutil_find_member().
Added classpath_free_search_result().
Modified:
harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c
Modified: harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c?view=diff&rev=565150&r1=565149&r2=565150
==============================================================================
--- harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c (original)
+++ harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/classpath.c Sun Aug 12 14:09:10 2007
@@ -9,8 +9,9 @@
* into it and not depend on the argument or environment pointers
* to always be unchanged.
*
- * The tmparea_init() function must have been called before these
- * functions so the internal @b CLASSPATH can be set up properly.
+ * If the @link #JVMCFG_TMPAREA_IN_USE temporary directory area@endlink
+ * is in use, the tmparea_init() function must have been called before
+ * these functions so the internal @b CLASSPATH can be set up properly.
*
*
* @section Control
@@ -73,10 +74,11 @@
* Break @b CLASSPATH apart into its constituent paths. Run once
* during startup to parse @b CLASSPATH. Heap management must be
* started before calling this function via HEAP_INIT(). The
- * command line must also have been scanned via argv_init().
+ * command line must also have been scanned via jvmargv_init().
*
- * The tmparea_init() function must have been called before these
- * functions so the internal @b CLASSPATH can be set up properly.
+ * If the @link #JVMCFG_TMPAREA_IN_USE temporary directory area@endlink
+ * is in use, the tmparea_init() function must have been called before
+ * these functions so the internal @b CLASSPATH can be set up properly.
*
*
* @param argc Number of arguments on command line
@@ -118,13 +120,20 @@
rint pathcount;
/*
- * Prepare to concatenate the temp directory area with actual
- * @b CLASSPATH, followed by potential
+ * Prepare to concatenate startup JAR file and the
+ * possible temporary directory area 'tmparea' with
+ * actual @b CLASSPATH, followed by potential
* CONFIG_HACKED_xxx definitions.
*/
- rchar *tmpclasspath; /* @b CLASSPATH dlm */
- rint tmpcplen =
+ rchar *moreclasspath; /* @b CLASSPATH dlm */
+ rint morecplen;
+ morecplen = (pjvm->startjar)
+ ? (portable_strlen(pjvm->startjar) + sizeof(rchar))
+ : 0;
+ morecplen +=
+#if JVMCFG_TMPAREA_IN_USE
portable_strlen(tmparea_get()) + sizeof(rchar) +
+#endif
portable_strlen(pjvm->classpath) + sizeof(rchar);
/*
@@ -133,89 +142,114 @@
*/
#ifdef CONFIG_HACKED_BOOTCLASSPATH
/* @b CLASSPATH dlm */
- tmpcplen +=
+ morecplen +=
portable_strlen(CONFIG_HACKED_BOOTCLASSPATH) + sizeof(rchar);
#endif
#ifdef CONFIG_HACKED_RTJARFILE
/* For $JAVA_HOME/$CONFIG_HACKED_RTJARFILE */
- tmpcplen += portable_strlen(pjvm->java_home);
- tmpcplen += sizeof(rchar);
- tmpcplen += portable_strlen(CONFIG_HACKED_RTJARFILE) +sizeof(rchar);
+ morecplen += portable_strlen(pjvm->java_home);
+ morecplen += sizeof(rchar);
+ morecplen += portable_strlen(CONFIG_HACKED_RTJARFILE)+sizeof(rchar);
#endif
- tmpcplen += sizeof(rchar);/* NUL byte, possibly 1 more than needed*/
+ morecplen += sizeof(rchar);/*NUL byte, possibly 1 more than needed*/
/*
* Allocate space for classpath image with temp area and
* possible CONFIG_HACKED_xxx adjustments
*/
- tmpclasspath = HEAP_GET_DATA(tmpcplen, rfalse);
+ moreclasspath = HEAP_GET_DATA(morecplen, rfalse);
/*
* Generate concatenation of
*
- * pjvm->TMPAREA:classpath:
-@link #CONFIG_HACKED_BOOTCLASSPATH CONFIG_HACKED_BOOTCLASSPATH@endlink:
- * @link #CONFIG_HACKED_RTJARFILE CONFIG_HACKED_RTJARFILE@endlink
+ * 1 pjvm->startjar:
+ * 2 pjvm->tmparea:
+ * 3 CLASSPATH:
+ * 4 @link #CONFIG_HACKED_BOOTCLASSPATH
+ CONFIG_HACKED_BOOTCLASSPATH@endlink:
+ * 5 @link #CONFIG_HACKED_RTJARFILE CONFIG_HACKED_RTJARFILE@endlink
*/
- portable_strcpy(tmpclasspath, tmparea_get());
- i = portable_strlen(tmpclasspath);
- tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
- tmpclasspath[i + 1] = '\0';
- portable_strcat(tmpclasspath, pjvm->classpath);
+ moreclasspath[0] = '\0';
+
+ if (pjvm->startjar) /* When using '-jar start.class.jar.file' form*/
+ {
+ portable_strcat(moreclasspath, pjvm->startjar);
+ i = portable_strlen(moreclasspath);
+ moreclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
+ moreclasspath[i + 1] = '\0';
+ }
+#if JVMCFG_TMPAREA_IN_USE
+ portable_strcat(moreclasspath, tmparea_get());
+ i = portable_strlen(moreclasspath);
+ moreclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
+ moreclasspath[i + 1] = '\0';
+#endif
+
+ portable_strcat(moreclasspath, pjvm->classpath);
#ifdef CONFIG_HACKED_BOOTCLASSPATH
- i = portable_strlen(tmpclasspath);
- tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
- tmpclasspath[i + 1] = '\0';
- portable_strcat(tmpclasspath, CONFIG_HACKED_BOOTCLASSPATH);
+ i = portable_strlen(moreclasspath);
+ moreclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
+ moreclasspath[i + 1] = '\0';
+ portable_strcat(moreclasspath, CONFIG_HACKED_BOOTCLASSPATH);
#endif
+
#ifdef CONFIG_HACKED_RTJARFILE
- i = portable_strlen(tmpclasspath);
- tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
- tmpclasspath[i + 1] = '\0';
- portable_strcat(tmpclasspath, pjvm->java_home);
-
- i = portable_strlen(tmpclasspath);
- tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
- tmpclasspath[i + 1] = '\0';
- portable_strcat(tmpclasspath, CONFIG_HACKED_RTJARFILE);
+ i = portable_strlen(moreclasspath);
+ moreclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
+ moreclasspath[i + 1] = '\0';
+ portable_strcat(moreclasspath, pjvm->java_home);
+
+ i = portable_strlen(moreclasspath);
+ moreclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR;
+ moreclasspath[i + 1] = '\0';
+ portable_strcat(moreclasspath, CONFIG_HACKED_RTJARFILE);
#endif
HEAP_FREE_DATA(pjvm->classpath); /* May or may not be on heap */
- pjvm->classpath = tmpclasspath; /* Keep for duration of pgm run */
-
+ pjvm->classpath = moreclasspath; /* Keep for duration of pgm run */
+
+ rint tcplen = portable_strlen(moreclasspath);
+
/* @warning NON-STANDARD TERMINATION CONDITION <= VERSUS < */
- for (i = 0, pathcount = 0; i <= portable_strlen(tmpclasspath); i++)
+ for (i = 0, pathcount = 0; i <= tcplen; i++)
{
- if ((CLASSPATH_ITEM_DELIMITER_CHAR == tmpclasspath[i]) ||
- (i == portable_strlen(tmpclasspath)))
+ if ((CLASSPATH_ITEM_DELIMITER_CHAR == moreclasspath[i]) ||
+ (i == tcplen))
{
pathcount++;
}
}
-
- /* Allocate space for list of @b CLASSPATH entries */
+ /* Allocate space for list of @b CLASSPATH entries, and using
+ * /absolute/path/names */
classpath_list = HEAP_GET_DATA(pathcount * sizeof(rchar *), rtrue);
rchar *nextpath;
rint thislen;
classpath_list_len = 0;
+ /*!
+ * @todo HARMONY-6-jvm-classpath.c-7 Check `pwd` overflow
+ * and @link #rnull rnull@endlink returned
+ */
+ rchar *pwd = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
+ portable_getwd(pwd);
+ portable_strcat(pwd, JVMCFG_PATHNAME_DELIMITER_STRING);
+ rint pwdlen = portable_strlen(pwd);
+
/* @warning NON-STANDARD TERMINATION CONDITION <= VERSUS < */
- for (i = 0, nextpath = tmpclasspath;
- i <= portable_strlen(tmpclasspath);
- i++)
+ for (i = 0, nextpath = moreclasspath; i <= tcplen; i++)
{
/* If found item delimiter OR END OF STRING (SEE ABOVE) */
- if ((CLASSPATH_ITEM_DELIMITER_CHAR == tmpclasspath[i]) ||
- (i == portable_strlen(tmpclasspath)))
+ if ((CLASSPATH_ITEM_DELIMITER_CHAR == moreclasspath[i]) ||
+ (i == tcplen))
{
/* calculate length of this @b CLASSPATH entry */
- thislen = (&tmpclasspath[i]) - nextpath;
+ thislen = (&moreclasspath[i]) - nextpath;
/*
* Ignore double-delimiter cases.
@@ -227,33 +261,91 @@
if (0 == thislen)
{
/* Pretend it was valid */
- nextpath = &tmpclasspath[i + 1];
+ nextpath = &moreclasspath[i + 1];
continue;
}
/*
* Allocate enough space for item, plus final '\0'.
+ * Add space for prefixed PWD if not already absolute.
+ * (For Windows, paths less than 3 characters cannot contain
+ * 'VOLUME:\...' form and so are copied directly.)
* Since we are scanning for a delimiter or EOS,
* the current length calculation includes the "1 + x"
* for the '\0'. The string[x] location is set to '\0'.
+ *
+ * If the path is of the form,
+ * /absolute/path/name or C:\absolute\path\name then
+ * simply copy it. Otherwise prefix /present/working/dir
+ * to make it absolute.
+ *
+ * Do not support Windows relative paths with volume
+ * prefix: D:..\dir\name
+ *
+ */
+
+ /*!
+ * @todo HARMONY-6-jvm-classpath.c-8 Document the lack of
+ * support for Windows relative paths with volume
+ * prefix: D:..\\dir\\name
+ *
*/
- classpath_list[classpath_list_len] =
- HEAP_GET_DATA(thislen + sizeof(rchar), rfalse);
+ if (
+#if defined(CONFIG_WINDOWS) || defined(CONFIG_CYGWIN)
+ (
+ (3 > thislen) ||
+ (isalpha(nextpath[0]) &&
+ (JVMCFG_PATHNAME_VOLUME_DELIMITER_CHAR ==
+ nextpath[1]) &&
+ (JVMCFG_PATHNAME_DELIMITER_CHAR ==
+ nextpath[2])))
+#if defined(CONFIG_CYGWIN)
+ ||
+ (JVMCFG_PATHNAME_ALT_DELIMITER_CHAR == nextpath[0])
+#endif
+#else
+ JVMCFG_PATHNAME_DELIMITER_CHAR == nextpath[0]
+#endif
+ )
+ {
+ classpath_list[classpath_list_len] =
+ HEAP_GET_DATA(thislen + sizeof(rchar), rfalse);
+ /* Store current @b CLASSPATH item, incl. final '\0' */
+ portable_memcpy(classpath_list[classpath_list_len],
+ nextpath,
+ thislen);
+ classpath_list[classpath_list_len][thislen] = '\0';
+ }
+ else
+ {
+ classpath_list[classpath_list_len] =
+ HEAP_GET_DATA(thislen + pwdlen + sizeof(rchar),
+ rfalse);
+
+ portable_strcpy(classpath_list[classpath_list_len],
+ pwd);
+
+ /* Store current @b CLASSPATH item, incl. final '\0' */
+ portable_memcpy(&classpath_list[classpath_list_len]
+ [pwdlen],
+ nextpath,
+ thislen);
+ classpath_list[classpath_list_len][thislen + pwdlen] =
+ '\0';
+ }
- /* Store current @b CLASSPATH item, including final '\0' */
- portable_memcpy(classpath_list[classpath_list_len],
- nextpath,
- thislen);
- classpath_list[classpath_list_len][thislen] = '\0';
classpath_list_len++;
/* Start looking at next @b CLASSPATH item */
- nextpath = &tmpclasspath[i + 1];
+ nextpath = &moreclasspath[i + 1];
- } /* if tmpclasspath[i] */
+ } /* if moreclasspath[i] */
} /* for i */
+ /* Clean up */
+ HEAP_FREE_DATA(pwd);
+
/* Declare this module initialized */
jvm_classpath_initialized = rtrue;
@@ -268,7 +360,8 @@
*
* A JAR file will be named @c @b /path/name/filename.jar, while a
* file name in a directory will be named
- * @c @b /path/name/ClassName.class .
+ * @c @b /path/name/ClassName.class . A JAR file may also be
+ * named @c @b /path/name/filename.zip for legacy reasons.
*
*
* @param pclasspath String from @b CLASSPATH list
@@ -282,37 +375,42 @@
{
ARCH_FUNCTION_NAME(classpath_isjar);
- rint len, jarlen;
+ rint len, jarlen, ext;
- /* Lengths of test string and of JAR extension (w/ name.ext dlm) */
- len = portable_strlen(pclasspath);
- jarlen = portable_strlen(JVMCFG_EXTENSION_DELIMITER_STRING) +
- portable_strlen(CLASSFILE_EXTENSION_JAR);
+ rchar *ext_list[2] = { CLASSFILE_EXTENSION_JAR,
+ CLASSFILE_EXTENSION_ZIP };
- /* For VERY short @b CLASSPATH entries, it cannot be a JAR file */
- if (jarlen >= len)
+ for (ext = 0; ext < 2; ext++)
{
- return(rfalse);
- }
+ /* Lengths of test string and of extension (w/ name.ext dlm) */
+ len = portable_strlen(pclasspath);
+ jarlen = portable_strlen(JVMCFG_EXTENSION_DELIMITER_STRING) +
+ portable_strlen(ext_list[ext]);
- /* Check if name.ext delimiter present in test string */
- if (JVMCFG_EXTENSION_DELIMITER_CHAR != pclasspath[len - jarlen])
- {
- return(rfalse);
- }
+ /* For VERY short @b CLASSPATH entries,it cannot be a JAR file*/
+ if (jarlen >= len)
+ {
+ continue;
+ }
- /* Now go test JAR extension since delimiter is present */
- jarlen--;
- if (0 == portable_strncmp(&pclasspath[len - jarlen],
- CLASSFILE_EXTENSION_JAR,
- jarlen))
- {
- return(rtrue);
- }
- else
- {
- return(rfalse);
- }
+ /* Check if name.ext delimiter present in test string */
+ if (JVMCFG_EXTENSION_DELIMITER_CHAR != pclasspath[len - jarlen])
+ {
+ continue;
+ }
+
+ /* Now go test JAR extension since delimiter is present */
+ jarlen--;
+ if (0 == portable_strncmp(&pclasspath[len - jarlen],
+ ext_list[ext],
+ jarlen))
+ {
+ return(rtrue);
+ }
+ } /* for ext */
+
+ /* JAR extension not found in list */
+ return(rfalse);
} /* END of classpath_isjar() */
@@ -387,6 +485,7 @@
} /* END of classpath_external2internal_classname_inplace() */
+#if 0
/*!
* @brief Adjust class name string for shell expansion artifacts.
*
@@ -455,6 +554,7 @@
return(outbfr);
} /* END of classpath_inner_class_adjust() */
+#endif
/*!
@@ -475,20 +575,28 @@
* to search for classes.
*
*
- * @param clsname Name of class, without @c @b .class
- * extension, as either @c @b some.class.name
- * or @c @b some/class/name , that is,
- * the internal form of the class name. The string
- * may or may not contain class formatting of the
- * form @c @b [[[Lsome/class/name;
- *
- *
- * @returns Heap pointer into @b CLASSPATH of directory or JAR file
- * containing class (for a regular .class file).
- * For a JAR file, report the name of the .jar file
- * as for a .class file, but also call classpath_isjar()
- * to distinguish between them. Thus the usage is,
- * Return @link #rnull rnull@endlink if no match.
+ * @param clsname Name of class, without @c @b .class extension, as
+ * as either @c @b some.package.name.SomeClassName
+ * or @c @b some/package/name/SomeClassName , that
+ * is, the external and internal forms of the class
+ * name, respectively. The string may or may not
+ * contain class formatting of the form
+ * @c @b [[[Lsome/package/name/SomeClassName;
+ *
+ *
+ * @returns Heap pointer containing @b CLASSPATH search result. This
+ * result will be a non-null pointer in one member of this
+ * structure which will indicate either a JAR file member or
+ * a simple class file. If result is a class file, simply
+ * open it, read, and close. If it is a JAR file member, read
+ * it with jarutil_read_current_member(), retrieve its buffer
+ * pointer, and close it. In both cases, free the indicated
+ * pointer when done. After this, free the heap pointer
+ * that was returned. (In other words, @e two heap pointers
+ * will need to be freed when done with the result.) If the
+ * returned heap pointer was @link #rnull rnull@endlink,
+ * then the class was not found in the @b CLASSPATH and an
+ * error needs to be indicated.
*
* @todo HARMONY-6-jvm-classpath.c-2 VM Spec section 5.3.1: Throw
* @b NoClassDeffoundError if no match.
@@ -501,27 +609,9 @@
* no <b><code>package some.package.name</code></b> statement
* in source.
*
- * @verbatim
- rchar *p = classpath_get_from_prchar(
- "some/package/name/SomeClassName");
-
- if (rnull != p)
- {
-
- if (rtrue == classpath_isjar(p))
- {
- ** Extract class from JAR file **
- }
- else
- {
- ** Read class file directly **
- }
- }
- @endverbatim
- *
*/
-rchar *classpath_get_from_prchar(rchar *clsname)
+classpath_search *classpath_get_from_prchar(rchar *clsname)
{
ARCH_FUNCTION_NAME(classpath_get_from_prchar);
@@ -531,13 +621,12 @@
rchar *name;
int baselen;
- rchar *class_location = HEAP_GET_DATA(JVMCFG_PATH_MAX, rfalse);
-
if (rtrue == nts_prchar_isclassformatted(clsname))
{
/*
* Convert @c @b [[[Lpath/name/ClassName; into
- * @c @b path/name/ClassName
+ * @c @b path/name/ClassName form using array dimensions plus
+ * data type specifier character 'L' (ie, add 1)
*/
jvm_array_dim arraydims = nts_get_prchar_arraydims(clsname);
name = &clsname[1 + arraydims];
@@ -564,7 +653,17 @@
baselen = portable_strlen(name);
}
+ /*
+ * Allocate result structure, zero it out since one member
+ * must be NULL upon return.
+ */
+ classpath_search *rc =HEAP_GET_DATA(sizeof(classpath_search),rtrue);
+
+ rchar *class_location = HEAP_GET_DATA(JVMCFG_PATH_MAX, rfalse);
+
+#if 0
rchar *jarscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
+#endif
/*
* Search through each entry in @b CLASSPATH for a file by
@@ -573,185 +672,109 @@
for (i = 0; i < classpath_list_len; i++)
{
- int clen;
-
/* Test for JAR files in @b CLASSPATH */
if (rtrue == classpath_isjar(classpath_list[i]))
{
/* Convert input parm to internal form, append suffix */
- portable_strcpy(class_location, name);
- clen = portable_strlen(class_location);
+ portable_strncpy(class_location, name, baselen);
+ class_location[baselen] = '\0';
+
(rvoid) classpath_external2internal_classname_inplace(
class_location);
- class_location[clen] = JVMCFG_EXTENSION_DELIMITER_CHAR;
- class_location[clen + 1] = '\0';
+ class_location[baselen] = JVMCFG_EXTENSION_DELIMITER_CHAR;
+ class_location[baselen + 1] = '\0';
portable_strcat(class_location,
CLASSFILE_EXTENSION_DEFAULT);
- rchar *inner_class_location =
- classpath_inner_class_adjust(class_location);
-
- /*!
- * @internal Build up JAR command using internal class name
- * with suffix. Make @e sure all files are
- * writeable for final <b><code>rm -rf</code></b>.
- */
- sprintfLocal(jarscript,
- JVMCFG_JARFILE_DATA_EXTRACT_SCRIPT,
- tmparea_get(),
- pjvm->java_home,
- pjvm->java_home,
- JVMCFG_PATHNAME_DELIMITER_CHAR,
- classpath_list[i],
- inner_class_location);
-
-#if defined(CONFIG_WINDOWS) || defined(CONFIG_CYGWIN)
-
+ jar_state *pjs = jarutil_find_member(classpath_list[i],
+ class_location,
+ HEAP_GET_DATA,
+ HEAP_FREE_DATA);
/*
- * @todo HARMONY-6-jvm-classpath.c-3
- * gmj : awful hack - need to escape out every \ in paths
- * or it doesn't seem to get across into the batch file
- * correctly
+ * Ignore this @b CLASSPATH entry if something was wrong
+ * with an input parameter, either the @b CLASSPATH entry
+ * itself or the @b clsname.
*/
- rchar *fixscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse);
-
- char *buffptr = fixscript;
- char *jarscriptPtr = jarscript;
-
- char c;
- while((c = *jarscriptPtr++))
+ if (rnull == pjs)
{
- *buffptr++ = c;
-
-#if defined(CONFIG_WINDOWS)
- if (c == JVMCFG_PATHNAME_DELIMITER_CHAR)
- {
- *buffptr++ = JVMCFG_PATHNAME_DELIMITER_CHAR;
- }
-#endif
-#if defined(CONFIG_CYGWIN)
- /*
- * CygWin can have both--
- * such as C:\\path\\name/more/path/name
- */
- if (c == JVMCFG_PATHNAME_ALT_DELIMITER_CHAR)
- {
- *buffptr++ = JVMCFG_PATHNAME_ALT_DELIMITER_CHAR;
- }
-#endif
+ continue;
}
- *buffptr = '\0';
-
- portable_strcpy(jarscript, fixscript);
- HEAP_FREE_DATA(fixscript);
-
-#endif
-
- HEAP_FREE_DATA(inner_class_location);
- int rc = portable_system(jarscript);
-
- if (0 != rc)
+ /* If match found, report to caller. Else keep looking */
+ if (pjs->jar_code != JAR_OKAY)
{
- sysErrMsg(arch_function_name,
- "Cannot extract '%s' from JAR file %s",
- inner_class_location,
- classpath_list[i]);
-
- HEAP_FREE_DATA(class_location);
- HEAP_FREE_DATA(jarscript);
+ if (JAR_MEMBER_IMPOSSIBLE_OPEN_FD != pjs->fd)
+ {
+ portable_close(pjs->fd);
+ }
- exit_jvm(EXIT_CLASSPATH_JAR);
-/*NOTREACHED*/
+ HEAP_FREE_DATA(pjs);
+ continue;
}
- /*
- * @todo HARMONY-6-jvm-classpath.c-4 Make sure that this
- * sprintf/stat works with both CONFIG_WINDOWS and
- * CONFIG_CYGWIN.
- *
- */
-
- /* Location of extracted file */
- sprintfLocal(jarscript,
- "%s%c%s",
- tmparea_get(),
- JVMCFG_PATHNAME_DELIMITER_CHAR,
- class_location);
-
- statbfr = portable_stat(jarscript);
- HEAP_FREE_DATA(statbfr);
-
- /*
- * If file was extracted, report result
- * in heap-allocated bfr
- */
- if (rnull != statbfr)
- {
- HEAP_FREE_DATA(class_location);
+ HEAP_FREE_DATA(class_location);
- return(jarscript);
- }
+ rc->jarfile_member_state = pjs;
- HEAP_FREE_DATA(jarscript);
+ return(rc);
}
else
{
- /*
- * @todo HARMONY-6-jvm-classpath.c-4 Make sure that this
+ /*!
+ * @todo HARMONY-6-jvm-classpath.c-6 Make sure that this
* sprintf/stat works with both CONFIG_WINDOWS and
* CONFIG_CYGWIN.
*
*/
- /* Convert input parm to internal form */
+ /* Convert input parm (directory name) to internal form */
sprintfLocal(class_location,
"%s%c\0",
classpath_list[i],
JVMCFG_PATHNAME_DELIMITER_CHAR);
- clen = portable_strlen(class_location);
+ int clen = portable_strlen(class_location);
portable_strcat(class_location, name);
/*
* Convert input parm to internal format and append
* class suffix, but convert @e only the @b name part
- * just appended, and not if if it is a JAR file.
+ * just appended.
*/
- if (rfalse == classpath_isjar(class_location))
- {
- (rvoid) classpath_external2internal_classname_inplace(
+ (rvoid) classpath_external2internal_classname_inplace(
&class_location[clen]);
- class_location[clen + baselen] =
+ class_location[clen + baselen] =
JVMCFG_EXTENSION_DELIMITER_CHAR;
- class_location[clen + baselen + 1] = '\0';
+ class_location[clen + baselen + 1] = '\0';
- portable_strcat(class_location,
- CLASSFILE_EXTENSION_DEFAULT);
- }
+ portable_strcat(class_location,CLASSFILE_EXTENSION_DEFAULT);
/* Test for existence of valid class file */
statbfr = portable_stat(class_location);
HEAP_FREE_DATA(statbfr);
- /* If match found, report result in heap-allocated bfr */
- if (rnull != statbfr)
+ /* If match found, report to caller. Else keep looking */
+ if (rnull == statbfr)
{
- HEAP_FREE_DATA(jarscript);
-
- return(class_location);
+ HEAP_FREE_DATA(class_location);
}
+
+ rc->classfile_name = class_location;
+
+ return(rc);
}
} /* for i */
/* Class not found in @b CLASSPATH */
HEAP_FREE_DATA(class_location);
+#if JVMCFG_TMPAREA_IN_USE
HEAP_FREE_DATA(jarscript);
+#endif
- return((rchar *) rnull);
+ return((classpath_search *) rnull);
} /* END of classpath_get_from_prchar() */
@@ -770,30 +793,72 @@
*
* @param clsname Name of class, without @c @b .class
* extension, as either @c @b some.class.name
- * or @c @b some/class/name , that is,
- * the internal form of the class name. The string
+ * or @c @b some/package/name/SomePackageName , that
+ * is, the internal form of the class name. The string
* may or may not contain class formatting of the
- * form @c @b [[[Lsome/class/name;
+ * form @c @b [[[Lsome/package/name/SomeClassName;
*
*
- * @returns Heap pointer into @b CLASSPATH of directory or JAR file
- * containing class (for a regular .class file).
+ * @returns Heap pointer containing @b CLASSPATH search result. If
+ * result is a class file, simply open it, read, and close.
+ * If it is a JAR file member, read it with
+ * jarutil_read_current_member(), retrieve its buffer pointer,
+ * and close it.
*
*/
-rchar *classpath_get_from_cp_entry_utf(cp_info_mem_align *clsname)
+classpath_search *classpath_get_from_cp_entry_utf(cp_info_mem_align
+ *clsname)
{
ARCH_FUNCTION_NAME(classpath_get_from_cp_entry_utf);
rchar *prchar_clsname = utf_utf2prchar(PTR_THIS_CP_Utf8(clsname));
- rchar *rc = classpath_get_from_prchar(prchar_clsname);
+ classpath_search *rc = classpath_get_from_prchar(prchar_clsname);
HEAP_FREE_DATA(prchar_clsname);
return(rc);
} /* END of classpath_get_from_cp_entry_utf() */
+
+
+/*!
+ * @brief Free up @b CLASSPATH search result pointer
+ *
+ * This structure contains two pointers, one of which is always NULL.
+ * Free the other one by attempting to free any non-NULL pointer, then
+ * free the enclosing structure pointer.
+ *
+ *
+ * @param pcpsr Heap pointer containing @b CLASSPATH search result to
+ * be freed.
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid classpath_free_search_result(classpath_search *pcpsr)
+{
+ /* Nothing to do if NULL pointer */
+ if (rnull == pcpsr)
+ {
+ return;
+ }
+
+ if (rnull != pcpsr->classfile_name)
+ {
+ HEAP_FREE_DATA(pcpsr->classfile_name);
+ }
+
+ if (rnull != pcpsr->jarfile_member_state)
+ {
+ HEAP_FREE_DATA(pcpsr->jarfile_member_state);
+ }
+
+ HEAP_FREE_DATA(pcpsr);
+ return;
+
+} /* END of classpath_free_search_result() */
/*!