Browse Source

fix license-script truncation

David Rose 17 years ago
parent
commit
aa6fa559c4

+ 128 - 0
ppremake/executionEnvironment.cxx

@@ -3,3 +3,131 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "executionEnvironment.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>  // for perror
+
+#ifdef WIN32_VC
+// Windows requires this for getcwd().
+#include <direct.h>
+#define getcwd _getcwd
+#endif
+
+////////////////////////////////////////////////////////////////////
+//     Function: ExecutionEnvironment::get_environment_variable
+//       Access: Public, Static
+//  Description: Returns the definition of the indicated environment
+//               variable, or the empty string if the variable is
+//               undefined.  The nonstatic implementation.
+////////////////////////////////////////////////////////////////////
+string ExecutionEnvironment::
+get_environment_variable(const string &var) {
+  const char *def = getenv(var.c_str());
+  if (def != (char *)NULL) {
+    return def;
+  }
+  return string();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ExecutionEnviroment::expand_string
+//       Access: Public, Static
+//  Description: Reads the string, looking for environment variable
+//               names marked by a $.  Expands all such variable
+//               names.  A repeated dollar sign ($$) is mapped to a
+//               single dollar sign.
+//
+//               Returns the expanded string.
+////////////////////////////////////////////////////////////////////
+string ExecutionEnvironment::
+expand_string(const string &str) {
+  string result;
+
+  size_t last = 0;
+  size_t dollar = str.find('$');
+  while (dollar != string::npos && dollar + 1 < str.length()) {
+    size_t start = dollar + 1;
+
+    if (str[start] == '$') {
+      // A double dollar sign maps to a single dollar sign.
+      result += str.substr(last, start - last);
+      last = start + 1;
+
+    } else {
+      string varname;
+      size_t end = start;
+
+      if (str[start] == '{') {
+        // Curly braces delimit the variable name explicitly.
+        end = str.find('}', start + 1);
+        if (end != string::npos) {
+          varname = str.substr(start + 1, end - (start + 1));
+          end++;
+        }
+      }
+
+      if (end == start) {
+        // Scan for the end of the variable name.
+        while (end < str.length() && (isalnum(str[end]) || str[end] == '_')) {
+          end++;
+        }
+        varname = str.substr(start, end - start);
+      }
+
+      string subst =
+      result += str.substr(last, dollar - last);
+      result += get_environment_variable(varname);
+      last = end;
+    }
+
+    dollar = str.find('$', last);
+  }
+
+  result += str.substr(last);
+
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: ExecutionEnviroment::get_cwd
+//       Access: Public, Static
+//  Description: Returns the name of the current working directory.
+////////////////////////////////////////////////////////////////////
+Filename ExecutionEnvironment::
+get_cwd() {
+  // getcwd() requires us to allocate a dynamic buffer and grow it on
+  // demand.
+  static size_t bufsize = 1024;
+  static char *buffer = NULL;
+
+  if (buffer == (char *)NULL) {
+    buffer = new char[bufsize];
+  }
+
+  while (getcwd(buffer, bufsize) == (char *)NULL) {
+    if (errno != ERANGE) {
+      perror("getcwd");
+      return string();
+    }
+    delete[] buffer;
+    bufsize = bufsize * 2;
+    buffer = new char[bufsize];
+    assert(buffer != (char *)NULL);
+  }
+
+  return Filename::from_os_specific(buffer);
+}

+ 29 - 0
ppremake/executionEnvironment.h

@@ -3,3 +3,32 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef EXECUTIONENVIRONMENT_H
+#define EXECUTIONENVIRONMENT_H
+
+#include "ppremake.h"
+#include "filename.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : ExecutionEnvironment
+// Description : This class is borrowed from dtool/src/dtoolutil, and
+//               stripped down to just the bare minimum that Filename
+//               needs; and also modified to build outside of Panda.
+////////////////////////////////////////////////////////////////////
+class ExecutionEnvironment {
+public:
+  static string get_environment_variable(const string &var);
+  static string expand_string(const string &str);
+  static Filename get_cwd();
+};
+
+#endif

+ 81 - 0
ppremake/globPattern.I

@@ -3,3 +3,84 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE GlobPattern::
+GlobPattern(const string &pattern) : _pattern(pattern) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::Copy Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE GlobPattern::
+GlobPattern(const GlobPattern &copy) : _pattern(copy._pattern) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::Copy Assignment Operator
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE void GlobPattern::
+operator = (const GlobPattern &copy) {
+  _pattern = copy._pattern;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::set_pattern
+//       Access: Public
+//  Description: Changes the pattern string that the GlobPattern
+//               object matches.
+////////////////////////////////////////////////////////////////////
+INLINE void GlobPattern::
+set_pattern(const string &pattern) {
+  _pattern = pattern;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::get_pattern
+//       Access: Public
+//  Description: Returns the pattern string that the GlobPattern
+//               object matches.
+////////////////////////////////////////////////////////////////////
+INLINE const string &GlobPattern::
+get_pattern() const {
+  return _pattern;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::matches
+//       Access: Public
+//  Description: Returns true if the candidate string matches the
+//               pattern, false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool GlobPattern::
+matches(const string &candidate) const {
+  return matches_substr(_pattern.begin(), _pattern.end(),
+                        candidate.begin(), candidate.end());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::output
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE void GlobPattern::
+output(ostream &out) const {
+  out << _pattern;
+}

+ 300 - 0
ppremake/globPattern.cxx

@@ -3,3 +3,303 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "globPattern.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::has_glob_characters
+//       Access: Public
+//  Description: Returns true if the pattern includes any special
+//               globbing characters, or false if it is just a literal
+//               string.
+////////////////////////////////////////////////////////////////////
+bool GlobPattern::
+has_glob_characters() const {
+  string::const_iterator pi;
+  pi = _pattern.begin();
+  while (pi != _pattern.end()) {
+    switch (*pi) {
+    case '*':
+    case '?':
+    case '[':
+      return true;
+
+    case '\\':
+      ++pi;
+      if (pi == _pattern.end()) {
+        return false;
+      }
+    }
+    ++pi;
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::match_files
+//       Access: Public
+//  Description: Treats the GlobPattern as a filename pattern, and
+//               returns a list of any actual files that match the
+//               pattern.  This is the behavior of the standard Posix
+//               glob() function.  Any part of the filename may
+//               contain glob characters, including intermediate
+//               directory names.
+//
+//               If cwd is specified, it is the directory that
+//               relative filenames are taken to be relative to;
+//               otherwise, the actual current working directory is
+//               assumed.
+//
+//               The return value is the number of files matched,
+//               which are added to the results vector.
+////////////////////////////////////////////////////////////////////
+int GlobPattern::
+match_files(vector_string &results, const Filename &cwd) {
+  string prefix, pattern, suffix;
+
+  string source = _pattern;
+  if (!source.empty() && source[0] == '/') {
+    // If the first character is a slash, that becomes the prefix.
+    prefix = "/";
+    source = source.substr(1);
+  }
+
+  size_t slash = source.find('/');
+  if (slash == string::npos) {
+    pattern = source;
+  } else {
+    pattern = source.substr(0, slash);
+    suffix = source.substr(slash + 1);
+  }
+  
+  GlobPattern glob(pattern);
+  return glob.r_match_files(prefix, suffix, results, cwd);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::r_match_files
+//       Access: Private
+//  Description: The recursive implementation of match_files().
+////////////////////////////////////////////////////////////////////
+int GlobPattern::
+r_match_files(const Filename &prefix, const string &suffix,
+              vector_string &results, const Filename &cwd) {
+  string next_pattern, next_suffix;
+
+  size_t slash = suffix.find('/');
+  if (slash == string::npos) {
+    next_pattern = suffix;
+  } else {
+    next_pattern = suffix.substr(0, slash);
+    next_suffix = suffix.substr(slash + 1);
+  }
+
+  Filename parent_dir;
+  if (prefix.is_local() && !cwd.empty()) {
+    parent_dir = Filename(cwd, prefix);
+  } else {
+    parent_dir = prefix;
+  }
+
+  GlobPattern next_glob(next_pattern);
+
+  if (!has_glob_characters()) {
+    // If there are no special characters in the pattern, it's a
+    // literal match.
+    if (suffix.empty()) {
+      // Time to stop.
+      Filename single_filename(parent_dir, _pattern);
+      if (single_filename.exists()) {
+        results.push_back(Filename(prefix, _pattern));
+        return 1;
+      }
+      return 0;
+    }
+
+    return next_glob.r_match_files(Filename(prefix, _pattern),
+                                   next_suffix, results, cwd);
+
+  } 
+
+  // If there *are* special glob characters, we must attempt to
+  // match the pattern against the files in this directory.
+  
+  vector_string dir_files;
+  if (!parent_dir.scan_directory(dir_files)) {
+    // Not a directory, or unable to read directory; stop here.
+    return 0;
+  }
+  
+  // Now go through each file in the directory looking for one that
+  // matches the pattern.
+  int num_matched = 0;
+  
+  vector_string::const_iterator fi;
+  for (fi = dir_files.begin(); fi != dir_files.end(); ++fi) {
+    const string &local_file = (*fi);
+    if (_pattern[0] == '.' || (local_file.empty() || local_file[0] != '.')) {
+      if (matches(local_file)) {
+        // We have a match; continue.
+        if (suffix.empty()) {
+          results.push_back(Filename(prefix, local_file));
+          num_matched++; 
+        } else {
+          num_matched += next_glob.r_match_files(Filename(prefix, local_file),
+                                                 next_suffix, results, cwd);
+        }
+      }
+    }
+  }
+  
+  return num_matched;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::matches_substr
+//       Access: Private
+//  Description: The recursive implementation of matches().  This
+//               returns true if the pattern substring [pi, pend)
+//               matches the candidate substring [ci, cend), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool GlobPattern::
+matches_substr(string::const_iterator pi, string::const_iterator pend,
+               string::const_iterator ci, string::const_iterator cend) const {
+  // If we run out of pattern or candidate string, it's a match only
+  // if they both ran out at the same time.
+  if (pi == pend || ci == cend) {
+    // A special exception: we allow ci to reach the end before pi,
+    // only if pi is one character before the end and that last
+    // character is '*'.
+    if ((ci == cend) && (pi + 1 == pend) && (*pi) == '*') {
+      return true;
+    }
+    return (pi == pend && ci == cend);
+  }
+
+  switch (*pi) {
+
+  case '*':
+    // A '*' in the pattern string means to match any sequence of zero
+    // or more characters in the candidate string.  This means we have
+    // to recurse twice: either consume one character of the candidate
+    // string and continue to try matching the *, or stop trying to
+    // match the * here.
+    return
+      matches_substr(pi, pend, ci + 1, cend) ||
+      matches_substr(pi + 1, pend, ci, cend);
+
+  case '?':
+    // A '?' in the pattern string means to match exactly one
+    // character in the candidate string.  That's easy.
+    return matches_substr(pi + 1, pend, ci + 1, cend);
+
+  case '[':
+    // An open square bracket begins a set.
+    ++pi;
+    if ((*pi) == '!') {
+      ++pi;
+      if (matches_set(pi, pend, *ci)) {
+        return false;
+      }
+    } else {
+      if (!matches_set(pi, pend, *ci)) {
+        return false;
+      }
+    }
+    if (pi == pend) {
+      // Oops, there wasn't a closing square bracket.
+      return false;
+    }
+    return matches_substr(pi + 1, pend, ci + 1, cend);
+
+  case '\\':
+    // A backslash escapes the next special character.
+    ++pi;
+    if (pi == pend) {
+      return false;
+    }
+    // fall through.
+
+  default:
+    // Anything else means to match exactly that.
+    if ((*pi) != (*ci)) {
+      return false;
+    }
+    return matches_substr(pi + 1, pend, ci + 1, cend);
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: GlobPattern::matches_set
+//       Access: Private
+//  Description: Called when an unescaped open square bracked is
+//               scanned, this is called with pi positioned after the
+//               opening square bracket, scans the set sequence,
+//               leaving pi positioned on the closing square bracket,
+//               and returns true if the indicated character matches
+//               the set of characters indicated, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool GlobPattern::
+matches_set(string::const_iterator &pi, string::const_iterator pend,
+            char ch) const {
+  bool matched = false;
+
+  while (pi != pend && (*pi) != ']') {
+    if ((*pi) == '\\') {
+      // Backslash escapes the next character.
+      ++pi;
+      if (pi == pend) {
+        return false;
+      }
+    }
+
+    if (ch == (*pi)) {
+      matched = true;
+    }
+
+    // Maybe it's an a-z style range?
+    char start = (*pi);
+    ++pi;
+    if (pi != pend && (*pi) == '-') {
+      ++pi;
+      if (pi != pend && (*pi) != ']') {
+        // Yes, we have a range: start-end.
+
+        if ((*pi) == '\\') {
+          // Backslash escapes.
+          ++pi;
+          if (pi == pend) {
+            return false;
+          }
+        }
+
+        char end = (*pi);
+        ++pi;
+
+        if (ch >= start && ch <= end) {
+          matched = true;
+        }
+      } else {
+        // This was a - at the end of the string.
+        if (ch == '-') {
+          matched = true;
+        }
+      }
+    }
+  }
+
+  return matched;
+}
+
+
+

+ 72 - 0
ppremake/globPattern.h

@@ -3,3 +3,75 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef GLOBPATTERN_H
+#define GLOBPATTERN_H
+
+#include "ppremake.h"
+#include "filename.h"
+#include "vector_string.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : GlobPattern
+// Description : This class can be used to test for string matches
+//               against standard Unix-shell filename globbing
+//               conventions.  It serves as a portable standin for the
+//               Posix fnmatch() call.
+//
+//               A GlobPattern is given a pattern string, which can
+//               contain operators like *, ?, and [].  Then it can be
+//               tested against any number of candidate strings; for
+//               each candidate, it will indicate whether the string
+//               matches the pattern or not.  It can be used, for
+//               example, to scan a directory for all files matching a
+//               particular pattern.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA GlobPattern {
+public:
+  INLINE GlobPattern(const string &pattern = string());
+  INLINE GlobPattern(const GlobPattern &copy);
+  INLINE void operator = (const GlobPattern &copy);
+
+  INLINE void set_pattern(const string &pattern);
+  INLINE const string &get_pattern() const;
+
+  INLINE bool matches(const string &candidate) const;
+
+  INLINE void output(ostream &out) const;
+
+  bool has_glob_characters() const;
+  int match_files(vector_string &results, const Filename &cwd = Filename());
+
+private:
+  bool matches_substr(string::const_iterator pi,
+                      string::const_iterator pend,
+                      string::const_iterator ci,
+                      string::const_iterator cend) const;
+
+  bool matches_set(string::const_iterator &pi,
+                   string::const_iterator pend,
+                   char ch) const;
+
+  int r_match_files(const Filename &prefix, const string &suffix,
+                    vector_string &results, const Filename &cwd);
+
+  string _pattern;
+};
+
+INLINE ostream &operator << (ostream &out, const GlobPattern &glob) {
+  glob.output(out);
+  return out;
+}
+
+
+#include "globPattern.I"
+
+#endif

+ 9 - 0
ppremake/ppremake.h

@@ -3,6 +3,15 @@
 // Created by:  drose (25Sep00)
 // 
 ////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
 */
 
 #ifndef PPREMAKE_H

+ 26 - 0
ppremake/vector_string.h

@@ -3,3 +3,29 @@
 //
 ////////////////////////////////////////////////////////////////////
 //
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef VECTOR_STRING_H
+#define VECTOR_STRING_H
+
+#include "ppremake.h"
+
+#include <vector>
+
+////////////////////////////////////////////////////////////////////
+//       Class : vector_string
+// Description : This typedef is borrowed from dtool/src/dtoolutil, and
+//               stripped down to just the bare minimum that Filename
+//               needs; and also modified to build outside of Panda.
+////////////////////////////////////////////////////////////////////
+
+typedef vector<string> vector_string;
+
+#endif