mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-12-07 20:08:48 +00:00
Move test fixtures to samples/
This commit is contained in:
458
test/fixtures/apex/ArrayUtils.cls
vendored
458
test/fixtures/apex/ArrayUtils.cls
vendored
@@ -1,458 +0,0 @@
|
||||
/* ============================================================
|
||||
* This code is part of the "apex-lang" open source project avaiable at:
|
||||
*
|
||||
* http://code.google.com/p/apex-lang/
|
||||
*
|
||||
* This code is licensed under the Apache License, Version 2.0. You may obtain a
|
||||
* copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* ============================================================
|
||||
*/
|
||||
global class ArrayUtils {
|
||||
|
||||
global static String[] EMPTY_STRING_ARRAY = new String[]{};
|
||||
global static Integer MAX_NUMBER_OF_ELEMENTS_IN_LIST {get{return 1000;}}
|
||||
|
||||
global static List<String> objectToString(List<Object> objects){
|
||||
List<String> strings = null;
|
||||
if(objects != null){
|
||||
strings = new List<String>();
|
||||
if(objects.size() > 0){
|
||||
for(Object obj : objects){
|
||||
if(obj instanceof String){
|
||||
strings.add((String)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
global static Object[] reverse(Object[] anArray) {
|
||||
if (anArray == null) {
|
||||
return null;
|
||||
}
|
||||
Integer i = 0;
|
||||
Integer j = anArray.size() - 1;
|
||||
Object tmp;
|
||||
while (j > i) {
|
||||
tmp = anArray[j];
|
||||
anArray[j] = anArray[i];
|
||||
anArray[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return anArray;
|
||||
}
|
||||
|
||||
global static SObject[] reverse(SObject[] anArray) {
|
||||
if (anArray == null) {
|
||||
return null;
|
||||
}
|
||||
Integer i = 0;
|
||||
Integer j = anArray.size() - 1;
|
||||
SObject tmp;
|
||||
while (j > i) {
|
||||
tmp = anArray[j];
|
||||
anArray[j] = anArray[i];
|
||||
anArray[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return anArray;
|
||||
}
|
||||
|
||||
global static List<String> lowerCase(List<String> strs){
|
||||
List<String> returnValue = null;
|
||||
if(strs != null){
|
||||
returnValue = new List<String>();
|
||||
if(strs.size() > 0){
|
||||
for(String str : strs){
|
||||
returnValue.add(str == null ? null : str.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static List<String> upperCase(List<String> strs){
|
||||
List<String> returnValue = null;
|
||||
if(strs != null){
|
||||
returnValue = new List<String>();
|
||||
if(strs.size() > 0){
|
||||
for(String str : strs){
|
||||
returnValue.add(str == null ? null : str.toUpperCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static List<String> trim(List<String> strs){
|
||||
List<String> returnValue = null;
|
||||
if(strs != null){
|
||||
returnValue = new List<String>();
|
||||
if(strs.size() > 0){
|
||||
for(String str : strs){
|
||||
returnValue.add(str == null ? null : str.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static Object[] mergex(Object[] array1, Object[] array2){
|
||||
if(array1 == null){ return array2; }
|
||||
if(array2 == null){ return array1; }
|
||||
Object[] merged = new Object[array1.size() + array2.size()];
|
||||
for(Integer i = 0; i < array1.size(); i++){
|
||||
merged[i] = array1[i];
|
||||
}
|
||||
for(Integer i = 0; i < array2.size(); i++){
|
||||
merged[i+array1.size()] = array2[i];
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
global static SObject[] mergex(SObject[] array1, SObject[] array2){
|
||||
if(array1 == null){ return array2; }
|
||||
if(array2 == null){ return array1; }
|
||||
if(array1.size() <= 0){ return array2; }
|
||||
List<SObject> merged = new List<SObject>();
|
||||
for(SObject sObj : array1){ merged.add(sObj); }
|
||||
for(SObject sObj : array2){ merged.add(sObj); }
|
||||
return merged;
|
||||
}
|
||||
|
||||
global static Boolean isEmpty(Object[] objectArray){
|
||||
if(objectArray == null){
|
||||
return true;
|
||||
}
|
||||
return objectArray.size() == 0;
|
||||
}
|
||||
|
||||
global static Boolean isEmpty(SObject[] objectArray){
|
||||
if(objectArray == null){
|
||||
return true;
|
||||
}
|
||||
return objectArray.size() == 0;
|
||||
}
|
||||
|
||||
global static Boolean isNotEmpty(Object[] objectArray){
|
||||
return !isEmpty(objectArray);
|
||||
}
|
||||
|
||||
global static Boolean isNotEmpty(SObject[] objectArray){
|
||||
return !isEmpty(objectArray);
|
||||
}
|
||||
|
||||
global static Object[] pluck(SObject[] objectArray, String fieldName){
|
||||
if(isEmpty(objectArray) || fieldName == null || fieldName.trim() == null || fieldName.trim().length() == 0){
|
||||
return new Object[]{};
|
||||
}
|
||||
Object[] plucked = new Object[objectArray.size()];
|
||||
for(Integer i = 0; i < objectArray.size(); i++){
|
||||
plucked[i] = objectArray[i].get(fieldName);
|
||||
}
|
||||
return plucked;
|
||||
}
|
||||
|
||||
|
||||
global static String toString(Object[] objectArray){
|
||||
if(objectArray == null){
|
||||
return 'null';
|
||||
}
|
||||
String returnValue = '{';
|
||||
for(Integer i = 0; i < objectArray.size(); i++){
|
||||
if(i!=0){ returnValue += ','; }
|
||||
returnValue += '\'' + objectArray[i] + '\'';
|
||||
}
|
||||
returnValue += '}';
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static String toString(SObject[] objectArray){
|
||||
if(objectArray == null){
|
||||
return 'null';
|
||||
}
|
||||
String returnValue = '{';
|
||||
for(Integer i = 0; i < objectArray.size(); i++){
|
||||
if(i!=0){ returnValue += ','; }
|
||||
returnValue += '\'' + objectArray[i] + '\'';
|
||||
}
|
||||
returnValue += '}';
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static void assertArraysAreEqual(Object[] expected, Object[] actual){
|
||||
//check to see if one param is null but the other is not
|
||||
System.assert((expected == null && actual == null)|| (expected != null && actual != null),
|
||||
'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
if(expected != null && actual != null){
|
||||
System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
for(Integer i = 0; i < expected.size(); i++){
|
||||
System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global static void assertArraysAreEqual(SObject[] expected, SObject[] actual){
|
||||
//check to see if one param is null but the other is not
|
||||
System.assert((expected == null && actual == null)|| (expected != null && actual != null),
|
||||
'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
if(expected != null && actual != null){
|
||||
System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
for(Integer i = 0; i < expected.size(); i++){
|
||||
System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global static List<Object> merg(List<Object> list1, List<Object> list2) {
|
||||
List<Object> returnList = new List<Object>();
|
||||
if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){
|
||||
throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST);
|
||||
}
|
||||
if(isNotEmpty(list1)){
|
||||
for(Object elmt : list1){
|
||||
returnList.add(elmt);
|
||||
}
|
||||
}
|
||||
if(isNotEmpty(list2)){
|
||||
for(Object elmt : list2){
|
||||
returnList.add(elmt);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
|
||||
global static List<SObject> merg(List<SObject> list1, List<SObject> list2) {
|
||||
if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){
|
||||
throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST);
|
||||
}
|
||||
if(isEmpty(list1) && isEmpty(list2)){
|
||||
return null;
|
||||
}
|
||||
List<SObject> returnList = new List<SObject>();
|
||||
if(list1 != null){
|
||||
for(SObject elmt : list1){
|
||||
returnList.add(elmt);
|
||||
}
|
||||
}
|
||||
if(list2 != null){
|
||||
for(SObject elmt : list2){
|
||||
returnList.add(elmt);
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
global static List<Object> subset(List<Object> aList, Integer count) {
|
||||
return subset(aList,0,count);
|
||||
}
|
||||
|
||||
global static List<Object> subset(List<Object> list1, Integer startIndex, Integer count) {
|
||||
List<Object> returnList = new List<Object>();
|
||||
if(list1 != null && list1.size() > 0 && startIndex >= 0 && startIndex <= list1.size()-1 && count > 0){
|
||||
for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){
|
||||
returnList.add(list1.get(i));
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
|
||||
global static List<SObject> subset(List<SObject> aList, Integer count) {
|
||||
return subset(aList,0,count);
|
||||
}
|
||||
|
||||
global static List<SObject> subset(List<SObject> list1, Integer startIndex, Integer count) {
|
||||
List<SObject> returnList = null;
|
||||
if(list1 != null && list1.size() > 0 && startIndex <= list1.size()-1 && count > 0){
|
||||
returnList = new List<SObject>();
|
||||
for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){
|
||||
returnList.add(list1.get(i));
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
//===============================================
|
||||
//LIST/ARRAY SORTING
|
||||
//===============================================
|
||||
|
||||
//FOR FORCE.COM PRIMITIVES (Double,Integer,ID,etc.):
|
||||
global static List<Object> qsort(List<Object> theList) {
|
||||
return qsort(theList,new PrimitiveComparator());
|
||||
}
|
||||
|
||||
global static List<Object> qsort(List<Object> theList, Boolean sortAsc) {
|
||||
return qsort(theList,new PrimitiveComparator(),sortAsc);
|
||||
}
|
||||
|
||||
global static List<Object> qsort(List<Object> theList, ObjectComparator comparator) {
|
||||
return qsort(theList,comparator,true);
|
||||
}
|
||||
|
||||
global static List<Object> qsort(List<Object> theList, ObjectComparator comparator, Boolean sortAsc) {
|
||||
return qsort(theList, 0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//FOR SALESFORCE OBJECTS (sObjects):
|
||||
global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator) {
|
||||
return qsort(theList,comparator,true);
|
||||
}
|
||||
|
||||
global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator,Boolean sortAsc ) {
|
||||
return qsort(theList, 0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc);
|
||||
}
|
||||
|
||||
private static List<Object> qsort(List<Object> theList,
|
||||
Integer lo0,
|
||||
Integer hi0,
|
||||
ObjectComparator comparator,
|
||||
Boolean sortAsc){
|
||||
Integer lo = lo0;
|
||||
Integer hi = hi0;
|
||||
|
||||
if (lo >= hi) {
|
||||
return theList;
|
||||
} else if( lo == hi - 1 ) {
|
||||
|
||||
if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||
|
||||
(comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)
|
||||
) {
|
||||
Object prs = theList[lo];
|
||||
theList[lo] = theList[hi];
|
||||
theList[hi] = prs;
|
||||
}
|
||||
return theList;
|
||||
}
|
||||
|
||||
Object pivot = theList[(lo + hi) / 2];
|
||||
theList[(lo + hi) / 2] = theList[hi];
|
||||
theList[hi] = pivot;
|
||||
|
||||
while( lo < hi ) {
|
||||
while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||
|
||||
(comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc)
|
||||
) { lo++; }
|
||||
while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) ||
|
||||
( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc)
|
||||
) { hi--; }
|
||||
|
||||
if( lo < hi ){
|
||||
Object prs = theList[lo];
|
||||
theList[lo] = theList[hi];
|
||||
theList[hi] = prs;
|
||||
}
|
||||
}
|
||||
|
||||
theList[hi0] = theList[hi];
|
||||
theList[hi] = pivot;
|
||||
|
||||
qsort(theList, lo0, lo-1,comparator,sortAsc);
|
||||
qsort(theList, hi+1, hi0,comparator,sortAsc);
|
||||
return theList;
|
||||
}
|
||||
|
||||
|
||||
private static List<SObject> qsort(List<SObject> theList,
|
||||
Integer lo0,
|
||||
Integer hi0,
|
||||
ISObjectComparator comparator,
|
||||
Boolean sortAsc){
|
||||
Integer lo = lo0;
|
||||
Integer hi = hi0;
|
||||
|
||||
if (lo >= hi) {
|
||||
return theList;
|
||||
} else if( lo == hi - 1 ) {
|
||||
|
||||
if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||
|
||||
(comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)
|
||||
) {
|
||||
SObject prs = theList[lo];
|
||||
theList[lo] = theList[hi];
|
||||
theList[hi] = prs;
|
||||
}
|
||||
return theList;
|
||||
}
|
||||
|
||||
SObject pivot = theList[(lo + hi) / 2];
|
||||
theList[(lo + hi) / 2] = theList[hi];
|
||||
theList[hi] = pivot;
|
||||
|
||||
while( lo < hi ) {
|
||||
while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||
|
||||
(comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc)
|
||||
) { lo++; }
|
||||
while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) ||
|
||||
( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc)
|
||||
) { hi--; }
|
||||
|
||||
if( lo < hi ){
|
||||
SObject prs = theList[lo];
|
||||
theList[lo] = theList[hi];
|
||||
theList[hi] = prs;
|
||||
}
|
||||
}
|
||||
|
||||
theList[hi0] = theList[hi];
|
||||
theList[hi] = pivot;
|
||||
|
||||
qsort(theList, lo0, lo-1,comparator,sortAsc);
|
||||
qsort(theList, hi+1, hi0,comparator,sortAsc);
|
||||
return theList;
|
||||
}
|
||||
/*
|
||||
global static List<Object> unique(List<Object> theList) {
|
||||
List<Object> uniques = new List<Object>();
|
||||
Set<Object> keys = new Set<Object>();
|
||||
if(theList != null && theList.size() > 0){
|
||||
for(Object obj : theList){
|
||||
if(keys.contains(obj)){
|
||||
continue;
|
||||
} else {
|
||||
keys.add(obj);
|
||||
uniques.add(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return uniques;
|
||||
}
|
||||
|
||||
global static List<SObject> unique(List<SObject> theList) {
|
||||
if(theList == null){
|
||||
return null;
|
||||
}
|
||||
List<SObject> uniques = createEmptySObjectList(theList.get(0));
|
||||
Set<String> keys = new Set<String>();
|
||||
if(theList != null && theList.size() > 0){
|
||||
String key = null;
|
||||
for(SObject obj : theList){
|
||||
key = obj == null ? null : ''+obj;
|
||||
if(keys.contains(key)){
|
||||
continue;
|
||||
} else {
|
||||
keys.add(key);
|
||||
uniques.add(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return uniques;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
185
test/fixtures/apex/BooleanUtils.cls
vendored
185
test/fixtures/apex/BooleanUtils.cls
vendored
@@ -1,185 +0,0 @@
|
||||
/* ============================================================
|
||||
* This code is part of the "apex-lang" open source project avaiable at:
|
||||
*
|
||||
* http://code.google.com/p/apex-lang/
|
||||
*
|
||||
* This code is licensed under the Apache License, Version 2.0. You may obtain a
|
||||
* copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* ============================================================
|
||||
*/
|
||||
global class BooleanUtils {
|
||||
|
||||
global static Boolean isFalse(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return false;
|
||||
else
|
||||
return !bool;
|
||||
}
|
||||
|
||||
global static Boolean isNotFalse(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return true;
|
||||
else
|
||||
return bool;
|
||||
}
|
||||
|
||||
global static Boolean isNotTrue(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return true;
|
||||
else
|
||||
return !bool;
|
||||
}
|
||||
|
||||
global static Boolean isTrue(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return false;
|
||||
else
|
||||
return bool;
|
||||
}
|
||||
|
||||
global static Boolean negate(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return null;
|
||||
else
|
||||
return !bool;
|
||||
}
|
||||
|
||||
global static Boolean toBooleanDefaultIfNull(Boolean bool, Boolean defaultVal)
|
||||
{
|
||||
if(bool==null)
|
||||
return defaultVal;
|
||||
else
|
||||
return bool;
|
||||
}
|
||||
|
||||
global static Boolean toBoolean(Integer value)
|
||||
{
|
||||
if(value==null)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if(value==0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
global static Boolean strToBoolean(String value)
|
||||
{
|
||||
if(value==null)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if(StringUtils.equalsIgnoreCase(value,'true'))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************/
|
||||
//Converts an int to a boolean specifying
|
||||
//the conversion values.
|
||||
// Parameters:
|
||||
// value - the Integer to convert, may be null
|
||||
// trueValue - the value to match for true, may be null
|
||||
// falseValue - the value to match for false, may be null
|
||||
//Returns:
|
||||
// true or false
|
||||
//Throws:
|
||||
// java.lang.IllegalArgumentException - if no match
|
||||
/************************************/
|
||||
global static Boolean toBoolean(Integer value,
|
||||
Integer trueValue,
|
||||
Integer falseValue)
|
||||
{
|
||||
if(value==trueValue)
|
||||
return true;
|
||||
else if(value==falseValue)
|
||||
return false;
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
|
||||
global static Integer toInteger(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
throw new IllegalArgumentException();
|
||||
else
|
||||
{
|
||||
if(bool)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
global static String toStringYesNo(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
if(bool)
|
||||
return 'yes';
|
||||
else
|
||||
return 'no';
|
||||
}
|
||||
}
|
||||
|
||||
global static String toStringYN(Boolean bool)
|
||||
{
|
||||
if(bool==null)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
if(bool)
|
||||
return 'Y';
|
||||
else
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
global static String toString(Boolean bool,
|
||||
String trueString,
|
||||
String falseString)
|
||||
{
|
||||
if(bool==null)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
if(bool)
|
||||
return trueString;
|
||||
else
|
||||
return falseString;
|
||||
}
|
||||
}
|
||||
|
||||
global static Boolean xor(Boolean[] boolArray)
|
||||
{
|
||||
if(boolArray==null || boolArray.size()==0)
|
||||
throw new IllegalArgumentException();
|
||||
else
|
||||
{
|
||||
Boolean firstItem=boolArray[0];
|
||||
for(Boolean bool:boolArray)
|
||||
{
|
||||
if(bool!=firstItem)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
98
test/fixtures/apex/EmailUtils.cls
vendored
98
test/fixtures/apex/EmailUtils.cls
vendored
@@ -1,98 +0,0 @@
|
||||
/* ============================================================
|
||||
* Contributor: Caleb Sidel
|
||||
*
|
||||
* This code is part of the "apex-lang" open source project avaiable at:
|
||||
*
|
||||
* http://code.google.com/p/apex-lang/
|
||||
*
|
||||
* This code is licensed under the Apache License, Version 2.0. You may obtain a
|
||||
* copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* ============================================================
|
||||
*/
|
||||
global class EmailUtils {
|
||||
|
||||
global static void sendEmailWithStandardAttachments(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Id> attachmentIDs) {
|
||||
List<Attachment> stdAttachments = [SELECT id, name, body FROM Attachment WHERE Id IN:attachmentIDs];
|
||||
sendEmailWithStandardAttachments(recipients, emailSubject, body, useHTML, stdAttachments);
|
||||
}
|
||||
|
||||
global static void sendEmailWithStandardAttachments(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Attachment> stdAttachments) {
|
||||
List<Messaging.EmailFileAttachment> fileAttachments = new List<Messaging.EmailFileAttachment>();
|
||||
|
||||
for(Attachment attachment : stdAttachments) {
|
||||
Messaging.EmailFileAttachment fileAttachment = new Messaging.EmailFileAttachment();
|
||||
fileAttachment.setFileName(attachment.Name);
|
||||
fileAttachment.setBody(attachment.Body);
|
||||
fileAttachments.add(fileAttachment);
|
||||
}
|
||||
sendEmail(recipients, emailSubject, body, useHTML, fileAttachments);
|
||||
}
|
||||
|
||||
global static void sendTextEmail(List<String> recipients,String emailSubject,String textBody) {
|
||||
sendEmail(recipients, emailSubject, textBody, false, null);
|
||||
}
|
||||
|
||||
global static void sendHTMLEmail(List<String> recipients,String emailSubject,String htmlBody) {
|
||||
sendEmail(recipients, emailSubject, htmlBody, true, null);
|
||||
}
|
||||
|
||||
global static void sendEmail(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Messaging.EmailFileAttachment> fileAttachments) {
|
||||
if(recipients == null) return;
|
||||
if(recipients.size() == 0) return;
|
||||
// Create a new single email message object
|
||||
// that will send out a single email to the addresses in the To, CC & BCC list.
|
||||
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
|
||||
//the email is not saved as an activity.
|
||||
mail.setSaveAsActivity(false);
|
||||
// Assign the addresses for the To lists to the mail object.
|
||||
mail.setToAddresses(recipients);
|
||||
// Specify the subject line for your email address.
|
||||
mail.setSubject(emailSubject);
|
||||
// Set to True if you want to BCC yourself on the email.
|
||||
mail.setBccSender(false);
|
||||
// The email address of the user executing the Apex Code will be used.
|
||||
mail.setUseSignature(false);
|
||||
if (useHTML) {
|
||||
// Specify the html content of the email.
|
||||
mail.setHtmlBody(body);
|
||||
} else {
|
||||
// Specify the text content of the email.
|
||||
mail.setPlainTextBody(body);
|
||||
}
|
||||
// Specify FileAttachments
|
||||
if(fileAttachments != null && fileAttachments.size() > 0) {
|
||||
mail.setFileAttachments(fileAttachments);
|
||||
}
|
||||
// Send the email you have created.
|
||||
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
|
||||
}
|
||||
|
||||
/**
|
||||
* null => false
|
||||
* '' => false
|
||||
* ' ' => false
|
||||
* 'x' => false
|
||||
* 'x@' => false
|
||||
* 'x@x' => false
|
||||
* 'x@x.x' => true
|
||||
*/
|
||||
global static Boolean isValidEmailAddress(String str){
|
||||
if(str != null && str.trim() != null && str.trim().length() > 0){
|
||||
String[] split = str.split('@');
|
||||
if(split != null && split.size() == 2){
|
||||
split = split[1].split('\\.');
|
||||
if(split != null && split.size() >= 2){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
global static Boolean isNotValidEmailAddress(String str){
|
||||
return !isValidEmailAddress(str);
|
||||
}
|
||||
|
||||
}
|
||||
55
test/fixtures/apex/GeoUtils.cls
vendored
55
test/fixtures/apex/GeoUtils.cls
vendored
@@ -1,55 +0,0 @@
|
||||
public class GeoUtils {
|
||||
// generate a KML string given a page reference, call getContent()
|
||||
// then cleanup the output.
|
||||
public static string generateFromContent(PageReference pr) {
|
||||
string ret = '';
|
||||
try {
|
||||
ret = (string) pr.getContent().toString();
|
||||
|
||||
ret = ret.replaceAll('"','\'' ); // get content produces quote chars \"
|
||||
ret = ret.replaceAll( '&','&');// we need to escape these in the node value
|
||||
} catch (exception e ) {
|
||||
system.debug( 'ERROR '+e);
|
||||
}
|
||||
|
||||
ret = ret.replaceAll('\n',' '); // must use ALL since many new line may get
|
||||
ret = ret.replaceAll('\r',' '); // get these also!
|
||||
// system.debug( ret); // dump the KML
|
||||
return ret ;
|
||||
}
|
||||
|
||||
public static Map<String, String> geo_response = new Map<String, String>{'200'=>'G_GEO_SUCCESS',
|
||||
'400'=>'G_GEO_BAD_REQUEST',
|
||||
'500'=>'G_GEO_SERVER_ERROR',
|
||||
'601'=>'G_GEO_MISSING_ADDRESS',
|
||||
'602'=>'G_GEO_UNKNOWN_ADDRESS',
|
||||
'603'=>'G_GEO_UNAVAILABLE_ADDRESS',
|
||||
'604'=>'G_GEO_UNKNOWN_DIRECTIONS',
|
||||
'610'=>'G_GEO_BAD_KEY',
|
||||
'620'=>'G_GEO_TOO_MANY_QUERIES'
|
||||
};
|
||||
|
||||
public static string accountAddressString ( account acct ) {
|
||||
// form an address string given an account object
|
||||
string adr = acct.billingstreet + ',' + acct.billingcity + ',' + acct.billingstate;
|
||||
if ( acct.billingpostalcode != null ) adr += ',' + acct.billingpostalcode;
|
||||
if ( acct.billingcountry != null ) adr += ',' + acct.billingcountry;
|
||||
adr = adr.replaceAll('\"', '' );
|
||||
adr = adr.replaceAll('\'', '' );
|
||||
adr = adr.replaceAll( '\n', ' ' );
|
||||
adr = adr.replaceAll( '\r', ' ' );
|
||||
system.debug( adr );
|
||||
return adr;
|
||||
}
|
||||
|
||||
public static testmethod void t1() {
|
||||
PageReference pageRef = Page.kmlPreviewTemplate;
|
||||
Test.setCurrentPage(pageRef);
|
||||
system.assert ( GeoUtils.generateFromContent( pageRef ) != null );
|
||||
Account a = new Account( name='foo', billingstreet='main', billingcity='springfield',billingstate='il',
|
||||
billingpostalcode='9',billingcountry='us');
|
||||
insert a;
|
||||
system.assertEquals( 'main,springfield,il,9,us',accountAddressString( a) );
|
||||
|
||||
}
|
||||
}
|
||||
740
test/fixtures/apex/LanguageUtils.cls
vendored
740
test/fixtures/apex/LanguageUtils.cls
vendored
@@ -1,740 +0,0 @@
|
||||
/* ============================================================
|
||||
* This code is part of the "apex-lang" open source project avaiable at:
|
||||
*
|
||||
* http://code.google.com/p/apex-lang/
|
||||
*
|
||||
* This code is licensed under the Apache License, Version 2.0. You may obtain a
|
||||
* copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* ============================================================
|
||||
*/
|
||||
global class LanguageUtils {
|
||||
|
||||
global static final String HTTP_LANGUAGE_CODE_PARAMETER_KEY = 'l';
|
||||
global static final String DEFAULT_LANGUAGE_CODE = 'en_us';
|
||||
|
||||
global static Set<String> SUPPORTED_LANGUAGE_CODES = new Set<String>{
|
||||
'zh-cn' //Chinese (Simplified)
|
||||
,'zh-tw' //Chinese (Traditional)
|
||||
,'nl-nl' //Dutch
|
||||
,'en-us' //English
|
||||
,'fi' //Finnish
|
||||
,'fr' //French
|
||||
,'de' //German
|
||||
,'it' //Italian
|
||||
,'ja' //Japanese
|
||||
,'ko' //Korean
|
||||
,'pl' //Polish
|
||||
,'pt-br' //Portuguese (Brazilian)
|
||||
,'ru' //Russian
|
||||
,'es' //Spanish
|
||||
,'sv' //Swedish
|
||||
,'th' //Thai
|
||||
,'cs' //Czech
|
||||
,'da' //Danish
|
||||
,'hu' //Hungarian
|
||||
,'in' //Indonesian
|
||||
,'tr' //Turkish
|
||||
};
|
||||
|
||||
private static Map<String,String> DEFAULTS = new Map<String,String>{
|
||||
'en'=>'en-us'
|
||||
,'zh'=>'zh-cn'
|
||||
,'nl'=>'nl-nl'
|
||||
,'pt'=>'pt-br'
|
||||
};
|
||||
|
||||
|
||||
global static String getLangCodeByHttpParam(){
|
||||
String returnValue = null;
|
||||
final Set<String> LANGUAGE_CODE_SET = getSuppLangCodeSet();
|
||||
if(ApexPages.currentPage() != null && ApexPages.currentPage().getParameters() != null){
|
||||
String LANGUAGE_HTTP_PARAMETER =
|
||||
StringUtils.lowerCase(
|
||||
StringUtils.replaceChars(
|
||||
ApexPages.currentPage().getParameters().get(HTTP_LANGUAGE_CODE_PARAMETER_KEY)
|
||||
, '_' //underscore
|
||||
, '-' //dash
|
||||
)
|
||||
);
|
||||
if(DEFAULTS.containsKey(LANGUAGE_HTTP_PARAMETER)){
|
||||
LANGUAGE_HTTP_PARAMETER = DEFAULTS.get(LANGUAGE_HTTP_PARAMETER);
|
||||
}
|
||||
if(StringUtils.isNotBlank(LANGUAGE_HTTP_PARAMETER)
|
||||
&& SUPPORTED_LANGUAGE_CODES.contains(LANGUAGE_HTTP_PARAMETER)){
|
||||
returnValue = LANGUAGE_HTTP_PARAMETER;
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
global static String getLangCodeByBrowser(){
|
||||
final String LANGUAGES_FROM_BROWSER_AS_STRING = ApexPages.currentPage().getHeaders().get('Accept-Language');
|
||||
final List<String> LANGUAGES_FROM_BROWSER_AS_LIST = splitAndFilterAcceptLanguageHeader(LANGUAGES_FROM_BROWSER_AS_STRING);
|
||||
if(LANGUAGES_FROM_BROWSER_AS_LIST != null && LANGUAGES_FROM_BROWSER_AS_LIST.size() > 0){
|
||||
for(String languageFromBrowser : LANGUAGES_FROM_BROWSER_AS_LIST){
|
||||
if(DEFAULTS.containsKey(languageFromBrowser)){
|
||||
languageFromBrowser = DEFAULTS.get(languageFromBrowser);
|
||||
}
|
||||
if(SUPPORTED_LANGUAGE_CODES.contains(languageFromBrowser)){
|
||||
return languageFromBrowser;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
global static String getLangCodeByUser(){
|
||||
return UserInfo.getLanguage();
|
||||
}
|
||||
|
||||
global static String getLangCodeByHttpParamOrIfNullThenBrowser(){
|
||||
return StringUtils.defaultString(getLangCodeByHttpParam(),getLangCodeByBrowser());
|
||||
}
|
||||
|
||||
global static String getLangCodeByHttpParamOrIfNullThenUser(){
|
||||
return StringUtils.defaultString(getLangCodeByHttpParam(),getLangCodeByUser());
|
||||
}
|
||||
|
||||
global static String getLangCodeByBrowserOrIfNullThenHttpParam(){
|
||||
return StringUtils.defaultString(getLangCodeByBrowser(),getLangCodeByHttpParam());
|
||||
}
|
||||
|
||||
global static String getLangCodeByBrowserOrIfNullThenUser(){
|
||||
return StringUtils.defaultString(getLangCodeByBrowser(),getLangCodeByUser());
|
||||
}
|
||||
|
||||
private static List<String> splitAndFilterAcceptLanguageHeader(String header){
|
||||
List<String> returnList = new List<String>();
|
||||
String[] tokens = StringUtils.split(header,',');
|
||||
if(tokens != null){
|
||||
for(String token : tokens){
|
||||
if(token != null ){
|
||||
if(token.contains(';')){
|
||||
token = token.substring(0,token.indexOf(';',0));
|
||||
}
|
||||
returnList.add(token);
|
||||
if(StringUtils.length(token) > 2){
|
||||
returnList.add(StringUtils.substring(token,0,2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private static Set<String> getSuppLangCodeSet(){
|
||||
Set<String> langCodes = new Set<String>();
|
||||
for(String langCode : SUPPORTED_LANGUAGE_CODES){
|
||||
if(langCode != null){
|
||||
langCodes.add(StringUtils.lowerCase(langCode));
|
||||
}
|
||||
}
|
||||
return langCodes;
|
||||
}
|
||||
|
||||
|
||||
global static String getLanguageName(String displayLanguageCode, String languageCode){
|
||||
return translatedLanguageNames.get(filterLanguageCode(displayLanguageCode)).get(filterLanguageCode(languageCode));
|
||||
}
|
||||
|
||||
global static Map<String,String> getAllLanguages(){
|
||||
return getAllLanguages(DEFAULT_LANGUAGE_CODE);
|
||||
}
|
||||
|
||||
global static Map<String,String> getAllLanguages(String displayLanguageCode){
|
||||
return translatedLanguageNames.get(filterLanguageCode(displayLanguageCode));
|
||||
}
|
||||
|
||||
private static String filterLanguageCode(String displayLanguageCode){
|
||||
displayLanguageCode = StringUtils.lowerCase(displayLanguageCode);
|
||||
if(DEFAULTS.containsKey(displayLanguageCode)){
|
||||
displayLanguageCode = StringUtils.replaceChars(DEFAULTS.get(displayLanguageCode),'-','_');
|
||||
}
|
||||
if(!translatedLanguageNames.containsKey(displayLanguageCode)){
|
||||
displayLanguageCode = DEFAULT_LANGUAGE_CODE;
|
||||
}
|
||||
return displayLanguageCode;
|
||||
}
|
||||
|
||||
private static final Map<String,Map<String,String>> translatedLanguageNames = new Map<String,Map<String,String>>{
|
||||
'cs'=> new Map<String,String>{
|
||||
'cs'=>'Čeština'
|
||||
,'da'=>'Dánština'
|
||||
,'de'=>'Němčina'
|
||||
,'en_us'=>'Angličtina (Spojené státy)'
|
||||
,'es'=>'Španělština'
|
||||
,'es_mx'=>'Mexická španělština'
|
||||
,'fi'=>'Finština'
|
||||
,'fr'=>'Francouzština'
|
||||
,'hu'=>'Maďarština'
|
||||
,'in'=>'Indonéština'
|
||||
,'it'=>'Italština'
|
||||
,'ja'=>'Japonština'
|
||||
,'ko'=>'Korejština'
|
||||
,'nl_nl'=>'Nizozemština'
|
||||
,'pl'=>'Polština'
|
||||
,'pt_br'=>'Portugalština (Brazílie)'
|
||||
,'ro'=>'Rumunština'
|
||||
,'ru'=>'Ruština'
|
||||
,'sv'=>'Švédština'
|
||||
,'th'=>'Thajská'
|
||||
,'tr'=>'Turečtina'
|
||||
,'zh_cn'=>'Čínština (zjednodušená)'
|
||||
,'zh_tw'=>'Čínština (tradiční)'
|
||||
}
|
||||
,'da'=> new Map<String,String>{
|
||||
'cs'=>'Tjekkisk'
|
||||
,'da'=>'Dansk'
|
||||
,'de'=>'Tysk'
|
||||
,'en_us'=>'Engelsk (USA)'
|
||||
,'es'=>'Spansk'
|
||||
,'es_mx'=>'Mexicansk spansk'
|
||||
,'fi'=>'Finsk'
|
||||
,'fr'=>'Fransk'
|
||||
,'hu'=>'Ungarsk'
|
||||
,'in'=>'Indonesisk'
|
||||
,'it'=>'Italiensk'
|
||||
,'ja'=>'Japansk'
|
||||
,'ko'=>'Koreansk'
|
||||
,'nl_nl'=>'Hollandsk'
|
||||
,'pl'=>'Polsk'
|
||||
,'pt_br'=>'Portugisisk (Brasilien)'
|
||||
,'ro'=>'Rumænsk'
|
||||
,'ru'=>'Russisk'
|
||||
,'sv'=>'Svensk'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Tyrkisk'
|
||||
,'zh_cn'=>'Kinesisk (forenklet)'
|
||||
,'zh_tw'=>'Kinesisk (traditionelt)'
|
||||
}
|
||||
,'de'=> new Map<String,String>{
|
||||
'cs'=>'Tschechisch'
|
||||
,'da'=>'Dänisch'
|
||||
,'de'=>'Deutsch'
|
||||
,'en_us'=>'Englisch (Vereinigte Staaten)'
|
||||
,'es'=>'Spanisch'
|
||||
,'es_mx'=>'Mexican Spanish'
|
||||
,'fi'=>'Finnisch'
|
||||
,'fr'=>'Französisch'
|
||||
,'hu'=>'Ungarisch'
|
||||
,'in'=>'Indonesisch'
|
||||
,'it'=>'Italienisch'
|
||||
,'ja'=>'Japanisch'
|
||||
,'ko'=>'Koreanisch'
|
||||
,'nl_nl'=>'Niederländisch'
|
||||
,'pl'=>'Polnisch'
|
||||
,'pt_br'=>'Portugiesisch (Brasilien)'
|
||||
,'ro'=>'Rumänisch'
|
||||
,'ru'=>'Russisch'
|
||||
,'sv'=>'Schwedisch'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Türkisch'
|
||||
,'zh_cn'=>'Chinesisch (Taiwan)'
|
||||
,'zh_tw'=>'Chinesisch (traditionell)'
|
||||
}
|
||||
,'en_us'=> new Map<String,String>{
|
||||
'cs'=>'Czech'
|
||||
,'da'=>'Danish'
|
||||
,'de'=>'German'
|
||||
,'en_us'=>'English (United States)'
|
||||
,'es'=>'Spanish'
|
||||
,'es_mx'=>'Mexican Spanish'
|
||||
,'fi'=>'Finnish'
|
||||
,'fr'=>'French'
|
||||
,'hu'=>'Hungarian'
|
||||
,'in'=>'Indonesian'
|
||||
,'it'=>'Italian'
|
||||
,'ja'=>'Japanese'
|
||||
,'ko'=>'Korean'
|
||||
,'nl_nl'=>'Dutch'
|
||||
,'pl'=>'Polish'
|
||||
,'pt_br'=>'Portuguese (Brazilian)'
|
||||
,'ro'=>'Romanian'
|
||||
,'ru'=>'Russian'
|
||||
,'sv'=>'Swedish'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turkish'
|
||||
,'zh_cn'=>'Chinese (Simplified)'
|
||||
,'zh_tw'=>'Chinese (Traditional)'
|
||||
}
|
||||
,'es'=> new Map<String,String>{
|
||||
'cs'=>'Checa'
|
||||
,'da'=>'Danés'
|
||||
,'de'=>'Alemán'
|
||||
,'en_us'=>'Inglés (Estados Unidos)'
|
||||
,'es'=>'Español'
|
||||
,'es_mx'=>'El español de México'
|
||||
,'fi'=>'Finlandés'
|
||||
,'fr'=>'Francés'
|
||||
,'hu'=>'Húngaro'
|
||||
,'in'=>'Indonesia'
|
||||
,'it'=>'Italiano'
|
||||
,'ja'=>'Japonés'
|
||||
,'ko'=>'Corea'
|
||||
,'nl_nl'=>'Neerlandés'
|
||||
,'pl'=>'Polaco'
|
||||
,'pt_br'=>'Portugués (brasileño)'
|
||||
,'ro'=>'Rumano'
|
||||
,'ru'=>'Rusia'
|
||||
,'sv'=>'Sueco'
|
||||
,'th'=>'Tailandia'
|
||||
,'tr'=>'Turquía'
|
||||
,'zh_cn'=>'Chino (simplificado)'
|
||||
,'zh_tw'=>'Chino (tradicional)'
|
||||
}
|
||||
,'es_mx'=> new Map<String,String>{
|
||||
'cs'=>'Checa'
|
||||
,'da'=>'Danés'
|
||||
,'de'=>'Alemán'
|
||||
,'en_us'=>'Inglés (Estados Unidos)'
|
||||
,'es'=>'Español'
|
||||
,'es_mx'=>'El español de México'
|
||||
,'fi'=>'Finlandés'
|
||||
,'fr'=>'Francés'
|
||||
,'hu'=>'Húngaro'
|
||||
,'in'=>'Indonesia'
|
||||
,'it'=>'Italiano'
|
||||
,'ja'=>'Japonés'
|
||||
,'ko'=>'Corea'
|
||||
,'nl_nl'=>'Neerlandés'
|
||||
,'pl'=>'Polaco'
|
||||
,'pt_br'=>'Portugués (brasileño)'
|
||||
,'ro'=>'Rumano'
|
||||
,'ru'=>'Rusia'
|
||||
,'sv'=>'Sueco'
|
||||
,'th'=>'Tailandia'
|
||||
,'tr'=>'Turquía'
|
||||
,'zh_cn'=>'Chino (simplificado)'
|
||||
,'zh_tw'=>'Chino (tradicional)'
|
||||
}
|
||||
,'fi'=> new Map<String,String>{
|
||||
'cs'=>'Tšekki'
|
||||
,'da'=>'Tanska'
|
||||
,'de'=>'Saksa'
|
||||
,'en_us'=>'Englanti (Yhdysvallat)'
|
||||
,'es'=>'Espanja'
|
||||
,'es_mx'=>'Meksikon espanja'
|
||||
,'fi'=>'Suomen'
|
||||
,'fr'=>'Ranska'
|
||||
,'hu'=>'Unkari'
|
||||
,'in'=>'Indonesia'
|
||||
,'it'=>'Italia'
|
||||
,'ja'=>'Japani'
|
||||
,'ko'=>'Korea'
|
||||
,'nl_nl'=>'Hollanti'
|
||||
,'pl'=>'Puola'
|
||||
,'pt_br'=>'Portugali (Brasilia)'
|
||||
,'ro'=>'Romania'
|
||||
,'ru'=>'Venäjä'
|
||||
,'sv'=>'Ruotsi'
|
||||
,'th'=>'Thaimaalaisen'
|
||||
,'tr'=>'Turkki'
|
||||
,'zh_cn'=>'Kiina (yksinkertaistettu)'
|
||||
,'zh_tw'=>'Kiina (perinteinen)'
|
||||
}
|
||||
,'fr'=> new Map<String,String>{
|
||||
'cs'=>'Tchèque'
|
||||
,'da'=>'Danois'
|
||||
,'de'=>'Allemand'
|
||||
,'en_us'=>'Anglais (Etats Unis)'
|
||||
,'es'=>'Espagnol'
|
||||
,'es_mx'=>'Espagnol mexicain'
|
||||
,'fi'=>'Finnois'
|
||||
,'fr'=>'Français'
|
||||
,'hu'=>'Hongrois'
|
||||
,'in'=>'Indonésien'
|
||||
,'it'=>'Italien'
|
||||
,'ja'=>'Japonais'
|
||||
,'ko'=>'Coréen'
|
||||
,'nl_nl'=>'Néerlandais'
|
||||
,'pl'=>'Polonais'
|
||||
,'pt_br'=>'Portugais (brésilien)'
|
||||
,'ro'=>'Roumain'
|
||||
,'ru'=>'Russe'
|
||||
,'sv'=>'Suédois'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turc'
|
||||
,'zh_cn'=>'Chinois (simplifié)'
|
||||
,'zh_tw'=>'Chinois (Traditionnel)'
|
||||
}
|
||||
,'hu'=> new Map<String,String>{
|
||||
'cs'=>'Cseh'
|
||||
,'da'=>'Dán'
|
||||
,'de'=>'Német'
|
||||
,'en_us'=>'Angol (Egyesült Államok)'
|
||||
,'es'=>'Spanyol'
|
||||
,'es_mx'=>'Mexikói spanyol'
|
||||
,'fi'=>'Finn'
|
||||
,'fr'=>'Francia'
|
||||
,'hu'=>'Magyar'
|
||||
,'in'=>'Indonéz'
|
||||
,'it'=>'Olasz'
|
||||
,'ja'=>'Japán'
|
||||
,'ko'=>'Koreai'
|
||||
,'nl_nl'=>'Holland'
|
||||
,'pl'=>'Lengyel'
|
||||
,'pt_br'=>'Portugál (brazíliai)'
|
||||
,'ro'=>'Román'
|
||||
,'ru'=>'Orosz'
|
||||
,'sv'=>'Svéd'
|
||||
,'th'=>'Thaiföldi'
|
||||
,'tr'=>'Török'
|
||||
,'zh_cn'=>'Kínai (egyszerűsített)'
|
||||
,'zh_tw'=>'Kínai (hagyományos)'
|
||||
}
|
||||
,'in'=> new Map<String,String>{
|
||||
'cs'=>'Ceko'
|
||||
,'da'=>'Denmark'
|
||||
,'de'=>'Jerman'
|
||||
,'en_us'=>'Inggris (Amerika Serikat)'
|
||||
,'es'=>'Spanyol'
|
||||
,'es_mx'=>'Meksiko Spanyol'
|
||||
,'fi'=>'Finlandia'
|
||||
,'fr'=>'Prancis'
|
||||
,'hu'=>'Hungaria'
|
||||
,'in'=>'Indonesia'
|
||||
,'it'=>'Italia'
|
||||
,'ja'=>'Jepang'
|
||||
,'ko'=>'Korea'
|
||||
,'nl_nl'=>'Belanda'
|
||||
,'pl'=>'Polish'
|
||||
,'pt_br'=>'Portugis (Brasil)'
|
||||
,'ro'=>'Romanian'
|
||||
,'ru'=>'Russian'
|
||||
,'sv'=>'Swedia'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turkish'
|
||||
,'zh_cn'=>'Cina (Sederhana)'
|
||||
,'zh_tw'=>'Cina (Tradisional)'
|
||||
}
|
||||
,'it'=> new Map<String,String>{
|
||||
'cs'=>'Ceco'
|
||||
,'da'=>'Danese'
|
||||
,'de'=>'Tedesco'
|
||||
,'en_us'=>'Inglese (Stati Uniti)'
|
||||
,'es'=>'Spagnolo'
|
||||
,'es_mx'=>'Spagnolo messicano'
|
||||
,'fi'=>'Finlandese'
|
||||
,'fr'=>'Francese'
|
||||
,'hu'=>'Ungherese'
|
||||
,'in'=>'Indonesiano'
|
||||
,'it'=>'Italiano'
|
||||
,'ja'=>'Giapponese'
|
||||
,'ko'=>'Coreano'
|
||||
,'nl_nl'=>'Olandese'
|
||||
,'pl'=>'Polacco'
|
||||
,'pt_br'=>'Portoghese (brasiliano)'
|
||||
,'ro'=>'Rumeno'
|
||||
,'ru'=>'Russo'
|
||||
,'sv'=>'Svedese'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turco'
|
||||
,'zh_cn'=>'Cinese (semplificato)'
|
||||
,'zh_tw'=>'Cinese (tradizionale)'
|
||||
}
|
||||
,'ja'=> new Map<String,String>{
|
||||
'cs'=>'チェコ語'
|
||||
,'da'=>'デンマーク語'
|
||||
,'de'=>'ドイツ語'
|
||||
,'en_us'=>'英語(アメリカ合衆国)'
|
||||
,'es'=>'スペイン語'
|
||||
,'es_mx'=>'メキシコのスペイン語'
|
||||
,'fi'=>'フィンランド語'
|
||||
,'fr'=>'フランス語'
|
||||
,'hu'=>'ハンガリー語'
|
||||
,'in'=>'インドネシア語'
|
||||
,'it'=>'イタリア語'
|
||||
,'ja'=>'日本語'
|
||||
,'ko'=>'韓国語'
|
||||
,'nl_nl'=>'オランダ語'
|
||||
,'pl'=>'ポーランド語'
|
||||
,'pt_br'=>'ポルトガル語(ブラジル)'
|
||||
,'ro'=>'ルーマニア語'
|
||||
,'ru'=>'ロシア語'
|
||||
,'sv'=>'スウェーデン語'
|
||||
,'th'=>'タイ'
|
||||
,'tr'=>'トルコ語'
|
||||
,'zh_cn'=>'中国語(簡体字)'
|
||||
,'zh_tw'=>'中国語(繁体字)'
|
||||
}
|
||||
,'ko'=> new Map<String,String>{
|
||||
'cs'=>'체코어'
|
||||
,'da'=>'덴마크어'
|
||||
,'de'=>'독일어'
|
||||
,'en_us'=>'영어 (미국)'
|
||||
,'es'=>'스페인어'
|
||||
,'es_mx'=>'멕시코 스페인'
|
||||
,'fi'=>'핀란드어'
|
||||
,'fr'=>'프랑스어'
|
||||
,'hu'=>'헝가리어'
|
||||
,'in'=>'인도네시 아어'
|
||||
,'it'=>'이탈리아어'
|
||||
,'ja'=>'일본어'
|
||||
,'ko'=>'한국어'
|
||||
,'nl_nl'=>'네덜란드'
|
||||
,'pl'=>'폴란드어'
|
||||
,'pt_br'=>'포르투갈어 (브라질)'
|
||||
,'ro'=>'루마니아어'
|
||||
,'ru'=>'러시아어'
|
||||
,'sv'=>'스웨덴어'
|
||||
,'th'=>'타이어'
|
||||
,'tr'=>'터키어'
|
||||
,'zh_cn'=>'중국어 (간체)'
|
||||
,'zh_tw'=>'중국어 (번체)'
|
||||
}
|
||||
,'nl_nl'=> new Map<String,String>{
|
||||
'cs'=>'Tsjechisch'
|
||||
,'da'=>'Deens'
|
||||
,'de'=>'Duits'
|
||||
,'en_us'=>'Engels (Verenigde Staten)'
|
||||
,'es'=>'Spaans'
|
||||
,'es_mx'=>'Mexicaans Spaans'
|
||||
,'fi'=>'Fins'
|
||||
,'fr'=>'Frans'
|
||||
,'hu'=>'Hongaars'
|
||||
,'in'=>'Indonesisch'
|
||||
,'it'=>'Italiaans'
|
||||
,'ja'=>'Japans'
|
||||
,'ko'=>'Koreaans'
|
||||
,'nl_nl'=>'Nederlandse'
|
||||
,'pl'=>'Pools'
|
||||
,'pt_br'=>'Portugees (Braziliaans)'
|
||||
,'ro'=>'Roemeens'
|
||||
,'ru'=>'Russisch'
|
||||
,'sv'=>'Zweeds'
|
||||
,'th'=>'Thais'
|
||||
,'tr'=>'Turks'
|
||||
,'zh_cn'=>'Chinese (Simplified)'
|
||||
,'zh_tw'=>'Chinees (traditioneel)'
|
||||
}
|
||||
,'pl'=> new Map<String,String>{
|
||||
'cs'=>'Czeski'
|
||||
,'da'=>'Duński'
|
||||
,'de'=>'Niemiecki'
|
||||
,'en_us'=>'Angielski (Stany Zjednoczone)'
|
||||
,'es'=>'Hiszpański'
|
||||
,'es_mx'=>'Mexican hiszpański'
|
||||
,'fi'=>'Fiński'
|
||||
,'fr'=>'Francuski'
|
||||
,'hu'=>'Węgierski'
|
||||
,'in'=>'Indonezyjski'
|
||||
,'it'=>'Włoski'
|
||||
,'ja'=>'Japoński'
|
||||
,'ko'=>'Koreański'
|
||||
,'nl_nl'=>'Niderlandzki'
|
||||
,'pl'=>'Polska'
|
||||
,'pt_br'=>'Portugalski (Brazylia)'
|
||||
,'ro'=>'Rumuński'
|
||||
,'ru'=>'Rosyjski'
|
||||
,'sv'=>'Szwedzki'
|
||||
,'th'=>'Taj'
|
||||
,'tr'=>'Turecki'
|
||||
,'zh_cn'=>'Chiński (uproszczony)'
|
||||
,'zh_tw'=>'Chiński (tradycyjny)'
|
||||
}
|
||||
,'pt_br'=> new Map<String,String>{
|
||||
'cs'=>'Tcheco'
|
||||
,'da'=>'Dinamarquês'
|
||||
,'de'=>'Alemão'
|
||||
,'en_us'=>'Inglês (Estados Unidos)'
|
||||
,'es'=>'Espanhol'
|
||||
,'es_mx'=>'Espanhol mexicano'
|
||||
,'fi'=>'Finlandês'
|
||||
,'fr'=>'Francês'
|
||||
,'hu'=>'Húngaro'
|
||||
,'in'=>'Indonésio'
|
||||
,'it'=>'Italiano'
|
||||
,'ja'=>'Japonês'
|
||||
,'ko'=>'Coreano'
|
||||
,'nl_nl'=>'Holandês'
|
||||
,'pl'=>'Polonês'
|
||||
,'pt_br'=>'Português (Brasil)'
|
||||
,'ro'=>'Romeno'
|
||||
,'ru'=>'Russo'
|
||||
,'sv'=>'Sueco'
|
||||
,'th'=>'Tailandês'
|
||||
,'tr'=>'Turco'
|
||||
,'zh_cn'=>'Chinês (simplificado)'
|
||||
,'zh_tw'=>'Chinês (Tradicional)'
|
||||
}
|
||||
,'ro'=> new Map<String,String>{
|
||||
'cs'=>'Cehă'
|
||||
,'da'=>'Daneză'
|
||||
,'de'=>'Germană'
|
||||
,'en_us'=>'În limba engleză (Statele Unite)'
|
||||
,'es'=>'Spaniolă'
|
||||
,'es_mx'=>'Mexicane Spanish'
|
||||
,'fi'=>'Finlandeză'
|
||||
,'fr'=>'Franţuzesc'
|
||||
,'hu'=>'Maghiară'
|
||||
,'in'=>'Indoneziană'
|
||||
,'it'=>'Italiană'
|
||||
,'ja'=>'Japoneză'
|
||||
,'ko'=>'Coreeană'
|
||||
,'nl_nl'=>'Olandeză'
|
||||
,'pl'=>'Poloneză'
|
||||
,'pt_br'=>'Portuguese (Brazilian)'
|
||||
,'ro'=>'Român'
|
||||
,'ru'=>'Rus'
|
||||
,'sv'=>'Suedez'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turcă'
|
||||
,'zh_cn'=>'Chineză (simplificată)'
|
||||
,'zh_tw'=>'Chineză (Tradiţională)'
|
||||
}
|
||||
,'ru'=> new Map<String,String>{
|
||||
'cs'=>'Чешский'
|
||||
,'da'=>'Датский'
|
||||
,'de'=>'Немецкий'
|
||||
,'en_us'=>'Английский (США)'
|
||||
,'es'=>'Испанский'
|
||||
,'es_mx'=>'Мексиканские Испанский'
|
||||
,'fi'=>'Финский'
|
||||
,'fr'=>'Французский'
|
||||
,'hu'=>'Венгерский'
|
||||
,'in'=>'Индонезийский'
|
||||
,'it'=>'Итальянский'
|
||||
,'ja'=>'Японский'
|
||||
,'ko'=>'Корейский'
|
||||
,'nl_nl'=>'Голландский'
|
||||
,'pl'=>'Польский'
|
||||
,'pt_br'=>'Португальский (бразильский)'
|
||||
,'ro'=>'Румынский'
|
||||
,'ru'=>'Русский'
|
||||
,'sv'=>'Шведский'
|
||||
,'th'=>'Тайский'
|
||||
,'tr'=>'Турецкий'
|
||||
,'zh_cn'=>'Китайский (упрощенный)'
|
||||
,'zh_tw'=>'Китайский (традиционный)'
|
||||
}
|
||||
,'sv'=> new Map<String,String>{
|
||||
'cs'=>'Tjeckiska'
|
||||
,'da'=>'Danska'
|
||||
,'de'=>'Tyska'
|
||||
,'en_us'=>'Engelska (USA)'
|
||||
,'es'=>'Spanska'
|
||||
,'es_mx'=>'Mexikansk spanska'
|
||||
,'fi'=>'Finska'
|
||||
,'fr'=>'Franska'
|
||||
,'hu'=>'Ungerska'
|
||||
,'in'=>'Indonesiska'
|
||||
,'it'=>'Italienska'
|
||||
,'ja'=>'Japanska'
|
||||
,'ko'=>'Koreanska'
|
||||
,'nl_nl'=>'Nederländska'
|
||||
,'pl'=>'Polska'
|
||||
,'pt_br'=>'Portugisiska (Brasilien)'
|
||||
,'ro'=>'Rumänska'
|
||||
,'ru'=>'Ryska'
|
||||
,'sv'=>'Svenska'
|
||||
,'th'=>'Thai'
|
||||
,'tr'=>'Turkiska'
|
||||
,'zh_cn'=>'Kinesiska (förenklad)'
|
||||
,'zh_tw'=>'Kinesiska (traditionell)'
|
||||
}
|
||||
,'th'=> new Map<String,String>{
|
||||
'cs'=>'สาธารณรัฐ เช็ ก'
|
||||
,'da'=>'เดนมาร์ก'
|
||||
,'de'=>'เยอรมัน'
|
||||
,'en_us'=>'ภาษา อังกฤษ States (United)'
|
||||
,'es'=>'สเปน'
|
||||
,'es_mx'=>'สเปน เม็ก ซิ กัน'
|
||||
,'fi'=>'ฟินแลนด์'
|
||||
,'fr'=>'ฝรั่งเศส'
|
||||
,'hu'=>'ฮังการี'
|
||||
,'in'=>'อินโดนีเซีย'
|
||||
,'it'=>'อิตาเลียน'
|
||||
,'ja'=>'ญี่ปุ่น'
|
||||
,'ko'=>'เกาหลี'
|
||||
,'nl_nl'=>'ดัตช์'
|
||||
,'pl'=>'เงา'
|
||||
,'pt_br'=>'โปรตุเกส (บราซิล)'
|
||||
,'ro'=>'โรมาเนีย'
|
||||
,'ru'=>'ภาษา รัสเซีย'
|
||||
,'sv'=>'สวีเดน'
|
||||
,'th'=>'ไทย'
|
||||
,'tr'=>'ภาษา ตุรกี'
|
||||
,'zh_cn'=>'จีน (ประยุกต์)'
|
||||
,'zh_tw'=>'ภาษา จีน (ดั้งเดิม)'
|
||||
}
|
||||
,'tr'=> new Map<String,String>{
|
||||
'cs'=>'Çekçe'
|
||||
,'da'=>'Danca'
|
||||
,'de'=>'Almanca'
|
||||
,'en_us'=>'İngilizce (ABD)'
|
||||
,'es'=>'İspanyolca'
|
||||
,'es_mx'=>'Mexican İspanyolca'
|
||||
,'fi'=>'Fince'
|
||||
,'fr'=>'Fransızca'
|
||||
,'hu'=>'Macarca'
|
||||
,'in'=>'Endonezya Dili'
|
||||
,'it'=>'İtalyanca'
|
||||
,'ja'=>'Japonca'
|
||||
,'ko'=>'Korece'
|
||||
,'nl_nl'=>'Hollanda Dili'
|
||||
,'pl'=>'Lehçe'
|
||||
,'pt_br'=>'Portekizce (Brezilya)'
|
||||
,'ro'=>'Romence'
|
||||
,'ru'=>'Rusça'
|
||||
,'sv'=>'İsveççe'
|
||||
,'th'=>'Tay'
|
||||
,'tr'=>'Türkçe'
|
||||
,'zh_cn'=>'Çince (Basitleştirilmiş)'
|
||||
,'zh_tw'=>'Çince (Geleneksel)'
|
||||
}
|
||||
,'zh_cn'=> new Map<String,String>{
|
||||
'cs'=>'捷克文'
|
||||
,'da'=>'丹麦文'
|
||||
,'de'=>'德语'
|
||||
,'en_us'=>'英语(美国)'
|
||||
,'es'=>'西班牙语'
|
||||
,'es_mx'=>'墨西哥西班牙语'
|
||||
,'fi'=>'芬兰文'
|
||||
,'fr'=>'法语'
|
||||
,'hu'=>'匈牙利文'
|
||||
,'in'=>'印度尼西亚文'
|
||||
,'it'=>'意大利语'
|
||||
,'ja'=>'日语'
|
||||
,'ko'=>'韩文'
|
||||
,'nl_nl'=>'荷兰文'
|
||||
,'pl'=>'波兰文'
|
||||
,'pt_br'=>'葡萄牙语(巴西)'
|
||||
,'ro'=>'罗马尼亚文'
|
||||
,'ru'=>'俄文'
|
||||
,'sv'=>'瑞典文'
|
||||
,'th'=>'泰国'
|
||||
,'tr'=>'土耳其文'
|
||||
,'zh_cn'=>'中文(简体)'
|
||||
,'zh_tw'=>'中文(繁体)'
|
||||
}
|
||||
,'zh_tw'=> new Map<String,String>{
|
||||
'cs'=>'捷克文'
|
||||
,'da'=>'丹麥文'
|
||||
,'de'=>'德語'
|
||||
,'en_us'=>'英語(美國)'
|
||||
,'es'=>'西班牙語'
|
||||
,'es_mx'=>'墨西哥西班牙語'
|
||||
,'fi'=>'芬蘭文'
|
||||
,'fr'=>'法語'
|
||||
,'hu'=>'匈牙利文'
|
||||
,'in'=>'印度尼西亞文'
|
||||
,'it'=>'意大利語'
|
||||
,'ja'=>'日語'
|
||||
,'ko'=>'韓文'
|
||||
,'nl_nl'=>'荷蘭文'
|
||||
,'pl'=>'波蘭文'
|
||||
,'pt_br'=>'葡萄牙語(巴西)'
|
||||
,'ro'=>'羅馬尼亞文'
|
||||
,'ru'=>'俄文'
|
||||
,'sv'=>'瑞典文'
|
||||
,'th'=>'泰國'
|
||||
,'tr'=>'土耳其文'
|
||||
,'zh_cn'=>'中文(簡體)'
|
||||
,'zh_tw'=>'中文(繁體)'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
114
test/fixtures/apex/TwilioAPI.cls
vendored
114
test/fixtures/apex/TwilioAPI.cls
vendored
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2012 Twilio, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/**
|
||||
* Entry point for accessing Twilio resources that are pre-configured
|
||||
* with credentials from the Twilio Config custom setting (TwilioConfig__c).
|
||||
*
|
||||
* To set up your Twilio credentials:
|
||||
* 1. Get a Twilio account at http://www.twilio.com/try-twilio
|
||||
* 2. Find your Twilio Account Sid and Auth Token at https://www.twilio.com/user/account
|
||||
* 3. Log into Salesforce and go to: Setup | Develop | Custom Settings | Manage Twilio Config
|
||||
* 4. Create a new Twilo Config instance
|
||||
* 5. Copy and paste your Account Sid and Auth Token and click Save
|
||||
*
|
||||
* NOTE: The Application Sid field is for use with the Twilio Client softphone
|
||||
* SDK for Javascript. It is not required for the rest of the Twilio API.
|
||||
*
|
||||
* Now you can get easy access to Twilio from your Apex code by calling:
|
||||
*
|
||||
* TwilioRestClient restClient = TwilioAPI.getDefaultClient();
|
||||
* restClient.getAccount().getCalls();
|
||||
* // etc.
|
||||
*/
|
||||
global class TwilioAPI {
|
||||
|
||||
private class MissingTwilioConfigCustomSettingsException extends Exception {}
|
||||
|
||||
private static TwilioRestClient client;
|
||||
|
||||
private TwilioAPI() {}
|
||||
|
||||
/**
|
||||
* Get a TwilioRestClient pre-populated with your TwilioConfig credentials
|
||||
*/
|
||||
public static TwilioRestClient getDefaultClient() {
|
||||
if (client==null) {
|
||||
TwilioConfig__c twilioCfg = getTwilioConfig();
|
||||
TwilioAPI.client = new TwilioRestClient(twilioCfg.AccountSid__c, twilioCfg.AuthToken__c);
|
||||
}
|
||||
return TwilioAPI.client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get your primary account using your TwilioConfig credentials
|
||||
*/
|
||||
public static TwilioAccount getDefaultAccount() {
|
||||
return getDefaultClient().getAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new Twilio Client capability token generator pre-populated
|
||||
* with your TwilioConfig credentials
|
||||
*/
|
||||
public static TwilioCapability createCapability() {
|
||||
TwilioConfig__c twilioCfg = getTwilioConfig();
|
||||
return new TwilioCapability(twilioCfg.AccountSid__c, twilioCfg.AuthToken__c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new TwilioRestClient authorized with the credentials provided
|
||||
*/
|
||||
public static TwilioRestClient createClient(String accountSid, String authToken) {
|
||||
return new TwilioRestClient(accountSid, authToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the org default TwilioConfig record
|
||||
*/
|
||||
public static TwilioConfig__c getTwilioConfig() {
|
||||
TwilioConfig__c twilioCfg;
|
||||
if (Test.isRunningTest()) {
|
||||
twilioCfg = new TwilioConfig__c();
|
||||
twilioCfg.AccountSid__c = 'ACba8bc05eacf94afdae398e642c9cc32d'; // dummy sid
|
||||
twilioCfg.AuthToken__c = '12345678901234567890123456789012'; // dummy token
|
||||
} else {
|
||||
twilioCfg = TwilioConfig__c.getOrgDefaults();
|
||||
if (twilioCfg==null)
|
||||
throw new MissingTwilioConfigCustomSettingsException('Please enter your Twilio account credentials under Twilio Config custom settings (go to Setup | Develop | Custom Settings | Manage Twilio Config)');
|
||||
}
|
||||
return twilioCfg;
|
||||
}
|
||||
|
||||
|
||||
@isTest
|
||||
static void test_TwilioAPI() {
|
||||
System.assertEquals('ACba8bc05eacf94afdae398e642c9cc32d', TwilioAPI.getTwilioConfig().AccountSid__c);
|
||||
System.assertEquals('12345678901234567890123456789012', TwilioAPI.getTwilioConfig().AuthToken__c);
|
||||
System.assertEquals('ACba8bc05eacf94afdae398e642c9cc32d', TwilioAPI.getDefaultClient().getAccountSid());
|
||||
System.assertEquals('ACba8bc05eacf94afdae398e642c9cc32d', TwilioAPI.getDefaultClient().getAccount().getSid());
|
||||
System.assertEquals('ACba8bc05eacf94afdae398e642c9cc32d', TwilioAPI.getDefaultAccount().getSid());
|
||||
}
|
||||
|
||||
}
|
||||
50
test/fixtures/applescript/center.applescript
vendored
50
test/fixtures/applescript/center.applescript
vendored
@@ -1,50 +0,0 @@
|
||||
set windowWidth to 800
|
||||
set windowHeight to 600
|
||||
delay 0.1
|
||||
|
||||
set AppleScript's text item delimiters to "x"
|
||||
|
||||
set res to text returned of (display dialog "Enter the width x height:" default answer ((windowWidth & windowHeight) as text))
|
||||
|
||||
if res is "" then
|
||||
display dialog "You need to enter a correct response"
|
||||
return
|
||||
end if
|
||||
set {windowWidth, windowHeight} to text items of res
|
||||
|
||||
set AppleScript's text item delimiters to ""
|
||||
|
||||
tell application "Safari"
|
||||
set screen_width to (do JavaScript "screen.availWidth" in document 1)
|
||||
set screen_height to (do JavaScript "screen.availHeight" in document 1)
|
||||
end tell
|
||||
|
||||
tell application "System Events"
|
||||
set myFrontMost to name of first item of (processes whose frontmost is true)
|
||||
end tell
|
||||
|
||||
tell application "Finder"
|
||||
set {desktopTop, desktopLeft, desktopRight, desktopBottom} to bounds of desktop
|
||||
end tell
|
||||
|
||||
try
|
||||
tell application "System Events"
|
||||
tell process myFrontMost
|
||||
set {{w, h}} to size of drawer of window 1
|
||||
end tell
|
||||
end tell
|
||||
on error
|
||||
set {w, h} to {0, 0}
|
||||
end try
|
||||
|
||||
tell application "System Events"
|
||||
tell process myFrontMost
|
||||
try
|
||||
set {{w, h}} to size of drawer of window 1
|
||||
on error
|
||||
set {w, h} to {0, 0}
|
||||
end try
|
||||
set position of window 1 to {((screen_width - windowWidth) / 2), ((screen_height - windowHeight) / 2.0) - desktopTop}
|
||||
set size of window 1 to {windowWidth -w, windowHeight}
|
||||
end tell
|
||||
end tell
|
||||
50
test/fixtures/applescript/center.scpt
vendored
50
test/fixtures/applescript/center.scpt
vendored
@@ -1,50 +0,0 @@
|
||||
set windowWidth to 800
|
||||
set windowHeight to 600
|
||||
delay 0.1
|
||||
|
||||
set AppleScript's text item delimiters to "x"
|
||||
|
||||
set res to text returned of (display dialog "Enter the width x height:" default answer ((windowWidth & windowHeight) as text))
|
||||
|
||||
if res is "" then
|
||||
display dialog "You need to enter a correct response"
|
||||
return
|
||||
end if
|
||||
set {windowWidth, windowHeight} to text items of res
|
||||
|
||||
set AppleScript's text item delimiters to ""
|
||||
|
||||
tell application "Safari"
|
||||
set screen_width to (do JavaScript "screen.availWidth" in document 1)
|
||||
set screen_height to (do JavaScript "screen.availHeight" in document 1)
|
||||
end tell
|
||||
|
||||
tell application "System Events"
|
||||
set myFrontMost to name of first item of (processes whose frontmost is true)
|
||||
end tell
|
||||
|
||||
tell application "Finder"
|
||||
set {desktopTop, desktopLeft, desktopRight, desktopBottom} to bounds of desktop
|
||||
end tell
|
||||
|
||||
try
|
||||
tell application "System Events"
|
||||
tell process myFrontMost
|
||||
set {{w, h}} to size of drawer of window 1
|
||||
end tell
|
||||
end tell
|
||||
on error
|
||||
set {w, h} to {0, 0}
|
||||
end try
|
||||
|
||||
tell application "System Events"
|
||||
tell process myFrontMost
|
||||
try
|
||||
set {{w, h}} to size of drawer of window 1
|
||||
on error
|
||||
set {w, h} to {0, 0}
|
||||
end try
|
||||
set position of window 1 to {((screen_width - windowWidth) / 2), ((screen_height - windowHeight) / 2.0) - desktopTop}
|
||||
set size of window 1 to {windowWidth -w, windowHeight}
|
||||
end tell
|
||||
end tell
|
||||
7
test/fixtures/arduino/hello.ino
vendored
7
test/fixtures/arduino/hello.ino
vendored
@@ -1,7 +0,0 @@
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Hello");
|
||||
}
|
||||
1
test/fixtures/autohotkey/hello.ahk
vendored
1
test/fixtures/autohotkey/hello.ahk
vendored
@@ -1 +0,0 @@
|
||||
MsgBox, Hello`, World!
|
||||
BIN
test/fixtures/binary/dog.o
vendored
BIN
test/fixtures/binary/dog.o
vendored
Binary file not shown.
BIN
test/fixtures/binary/foo bar.jar
vendored
BIN
test/fixtures/binary/foo bar.jar
vendored
Binary file not shown.
BIN
test/fixtures/binary/foo.bin
vendored
BIN
test/fixtures/binary/foo.bin
vendored
Binary file not shown.
BIN
test/fixtures/binary/foo.pdf
vendored
BIN
test/fixtures/binary/foo.pdf
vendored
Binary file not shown.
BIN
test/fixtures/binary/foo.png
vendored
BIN
test/fixtures/binary/foo.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 5.4 KiB |
BIN
test/fixtures/binary/git.deb
vendored
BIN
test/fixtures/binary/git.deb
vendored
Binary file not shown.
BIN
test/fixtures/binary/git.exe
vendored
BIN
test/fixtures/binary/git.exe
vendored
Binary file not shown.
21
test/fixtures/binary/github.po
vendored
21
test/fixtures/binary/github.po
vendored
@@ -1,21 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: x\n"
|
||||
"POT-Creation-Date: 2009-02-15 09:22+0100\n"
|
||||
"PO-Revision-Date: 2009-02-15 09:22+0100\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||
|
||||
#: tools/files/simple_translation.rb:1
|
||||
msgid "a translation"
|
||||
msgstr ""
|
||||
BIN
test/fixtures/binary/hello.pbc
vendored
BIN
test/fixtures/binary/hello.pbc
vendored
Binary file not shown.
BIN
test/fixtures/binary/linguist.gem
vendored
BIN
test/fixtures/binary/linguist.gem
vendored
Binary file not shown.
4424
test/fixtures/binary/octocat.ai
vendored
4424
test/fixtures/binary/octocat.ai
vendored
File diff suppressed because one or more lines are too long
BIN
test/fixtures/binary/octocat.png
vendored
BIN
test/fixtures/binary/octocat.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 5.4 KiB |
BIN
test/fixtures/binary/octocat.psd
vendored
BIN
test/fixtures/binary/octocat.psd
vendored
Binary file not shown.
BIN
test/fixtures/binary/zip
vendored
BIN
test/fixtures/binary/zip
vendored
Binary file not shown.
25
test/fixtures/c/blob.c
vendored
25
test/fixtures/c/blob.c
vendored
@@ -1,25 +0,0 @@
|
||||
#include "cache.h"
|
||||
#include "blob.h"
|
||||
|
||||
const char *blob_type = "blob";
|
||||
|
||||
struct blob *lookup_blob(const unsigned char *sha1)
|
||||
{
|
||||
struct object *obj = lookup_object(sha1);
|
||||
if (!obj)
|
||||
return create_object(sha1, OBJ_BLOB, alloc_blob_node());
|
||||
if (!obj->type)
|
||||
obj->type = OBJ_BLOB;
|
||||
if (obj->type != OBJ_BLOB) {
|
||||
error("Object %s is a %s, not a blob",
|
||||
sha1_to_hex(sha1), typename(obj->type));
|
||||
return NULL;
|
||||
}
|
||||
return (struct blob *) obj;
|
||||
}
|
||||
|
||||
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
|
||||
{
|
||||
item->object.parsed = 1;
|
||||
return 0;
|
||||
}
|
||||
25
test/fixtures/c/blob.h
vendored
25
test/fixtures/c/blob.h
vendored
@@ -1,25 +0,0 @@
|
||||
#ifndef BLOB_H
|
||||
#define BLOB_H
|
||||
|
||||
#include "object.h"
|
||||
|
||||
extern const char *blob_type;
|
||||
|
||||
struct blob {
|
||||
struct object object;
|
||||
};
|
||||
|
||||
struct blob *lookup_blob(const unsigned char *sha1);
|
||||
|
||||
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size);
|
||||
|
||||
/**
|
||||
* Blobs do not contain references to other objects and do not have
|
||||
* structured data that needs parsing. However, code may use the
|
||||
* "parsed" bit in the struct object for a blob to determine whether
|
||||
* its content has been found to actually be available, so
|
||||
* parse_blob_buffer() is used (by object.c) to flag that the object
|
||||
* has been read successfully from the database.
|
||||
**/
|
||||
|
||||
#endif /* BLOB_H */
|
||||
99
test/fixtures/c/cache.c
vendored
99
test/fixtures/c/cache.c
vendored
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "repository.h"
|
||||
#include "commit.h"
|
||||
#include "thread-utils.h"
|
||||
#include "util.h"
|
||||
#include "cache.h"
|
||||
|
||||
int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr)
|
||||
{
|
||||
if (size < 8)
|
||||
size = 8;
|
||||
size = git__size_t_powerof2(size);
|
||||
|
||||
cache->size_mask = size - 1;
|
||||
cache->lru_count = 0;
|
||||
cache->free_obj = free_ptr;
|
||||
|
||||
git_mutex_init(&cache->lock);
|
||||
|
||||
cache->nodes = git__malloc(size * sizeof(git_cached_obj *));
|
||||
GITERR_CHECK_ALLOC(cache->nodes);
|
||||
|
||||
memset(cache->nodes, 0x0, size * sizeof(git_cached_obj *));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_cache_free(git_cache *cache)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (cache->size_mask + 1); ++i) {
|
||||
if (cache->nodes[i] != NULL)
|
||||
git_cached_obj_decref(cache->nodes[i], cache->free_obj);
|
||||
}
|
||||
|
||||
git__free(cache->nodes);
|
||||
}
|
||||
|
||||
void *git_cache_get(git_cache *cache, const git_oid *oid)
|
||||
{
|
||||
uint32_t hash;
|
||||
git_cached_obj *node = NULL, *result = NULL;
|
||||
|
||||
memcpy(&hash, oid->id, sizeof(hash));
|
||||
|
||||
git_mutex_lock(&cache->lock);
|
||||
{
|
||||
node = cache->nodes[hash & cache->size_mask];
|
||||
|
||||
if (node != NULL && git_oid_cmp(&node->oid, oid) == 0) {
|
||||
git_cached_obj_incref(node);
|
||||
result = node;
|
||||
}
|
||||
}
|
||||
git_mutex_unlock(&cache->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *git_cache_try_store(git_cache *cache, void *_entry)
|
||||
{
|
||||
git_cached_obj *entry = _entry;
|
||||
uint32_t hash;
|
||||
|
||||
memcpy(&hash, &entry->oid, sizeof(uint32_t));
|
||||
|
||||
/* increase the refcount on this object, because
|
||||
* the cache now owns it */
|
||||
git_cached_obj_incref(entry);
|
||||
|
||||
git_mutex_lock(&cache->lock);
|
||||
{
|
||||
git_cached_obj *node = cache->nodes[hash & cache->size_mask];
|
||||
|
||||
if (node == NULL) {
|
||||
cache->nodes[hash & cache->size_mask] = entry;
|
||||
} else if (git_oid_cmp(&node->oid, &entry->oid) == 0) {
|
||||
git_cached_obj_decref(entry, cache->free_obj);
|
||||
entry = node;
|
||||
} else {
|
||||
git_cached_obj_decref(node, cache->free_obj);
|
||||
cache->nodes[hash & cache->size_mask] = entry;
|
||||
}
|
||||
}
|
||||
git_mutex_unlock(&cache->lock);
|
||||
|
||||
/* increase the refcount again, because we are
|
||||
* returning it to the user */
|
||||
git_cached_obj_incref(entry);
|
||||
|
||||
return entry;
|
||||
}
|
||||
1228
test/fixtures/c/commit.c
vendored
1228
test/fixtures/c/commit.c
vendored
File diff suppressed because it is too large
Load Diff
226
test/fixtures/c/commit.h
vendored
226
test/fixtures/c/commit.h
vendored
@@ -1,226 +0,0 @@
|
||||
#ifndef COMMIT_H
|
||||
#define COMMIT_H
|
||||
|
||||
#include "object.h"
|
||||
#include "tree.h"
|
||||
#include "strbuf.h"
|
||||
#include "decorate.h"
|
||||
|
||||
struct commit_list {
|
||||
struct commit *item;
|
||||
struct commit_list *next;
|
||||
};
|
||||
|
||||
struct commit {
|
||||
struct object object;
|
||||
void *util;
|
||||
unsigned int indegree;
|
||||
unsigned long date;
|
||||
struct commit_list *parents;
|
||||
struct tree *tree;
|
||||
char *buffer;
|
||||
};
|
||||
|
||||
extern int save_commit_buffer;
|
||||
extern const char *commit_type;
|
||||
|
||||
/* While we can decorate any object with a name, it's only used for commits.. */
|
||||
extern struct decoration name_decoration;
|
||||
struct name_decoration {
|
||||
struct name_decoration *next;
|
||||
int type;
|
||||
char name[1];
|
||||
};
|
||||
|
||||
struct commit *lookup_commit(const unsigned char *sha1);
|
||||
struct commit *lookup_commit_reference(const unsigned char *sha1);
|
||||
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
|
||||
int quiet);
|
||||
struct commit *lookup_commit_reference_by_name(const char *name);
|
||||
|
||||
/*
|
||||
* Look up object named by "sha1", dereference tag as necessary,
|
||||
* get a commit and return it. If "sha1" does not dereference to
|
||||
* a commit, use ref_name to report an error and die.
|
||||
*/
|
||||
struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_name);
|
||||
|
||||
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
|
||||
int parse_commit(struct commit *item);
|
||||
|
||||
/* Find beginning and length of commit subject. */
|
||||
int find_commit_subject(const char *commit_buffer, const char **subject);
|
||||
|
||||
struct commit_list *commit_list_insert(struct commit *item,
|
||||
struct commit_list **list);
|
||||
struct commit_list **commit_list_append(struct commit *commit,
|
||||
struct commit_list **next);
|
||||
unsigned commit_list_count(const struct commit_list *l);
|
||||
struct commit_list *commit_list_insert_by_date(struct commit *item,
|
||||
struct commit_list **list);
|
||||
void commit_list_sort_by_date(struct commit_list **list);
|
||||
|
||||
void free_commit_list(struct commit_list *list);
|
||||
|
||||
/* Commit formats */
|
||||
enum cmit_fmt {
|
||||
CMIT_FMT_RAW,
|
||||
CMIT_FMT_MEDIUM,
|
||||
CMIT_FMT_DEFAULT = CMIT_FMT_MEDIUM,
|
||||
CMIT_FMT_SHORT,
|
||||
CMIT_FMT_FULL,
|
||||
CMIT_FMT_FULLER,
|
||||
CMIT_FMT_ONELINE,
|
||||
CMIT_FMT_EMAIL,
|
||||
CMIT_FMT_USERFORMAT,
|
||||
|
||||
CMIT_FMT_UNSPECIFIED
|
||||
};
|
||||
|
||||
struct pretty_print_context {
|
||||
enum cmit_fmt fmt;
|
||||
int abbrev;
|
||||
const char *subject;
|
||||
const char *after_subject;
|
||||
int preserve_subject;
|
||||
enum date_mode date_mode;
|
||||
unsigned date_mode_explicit:1;
|
||||
int need_8bit_cte;
|
||||
int show_notes;
|
||||
struct reflog_walk_info *reflog_info;
|
||||
const char *output_encoding;
|
||||
};
|
||||
|
||||
struct userformat_want {
|
||||
unsigned notes:1;
|
||||
};
|
||||
|
||||
extern int has_non_ascii(const char *text);
|
||||
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
|
||||
extern char *logmsg_reencode(const struct commit *commit,
|
||||
const char *output_encoding);
|
||||
extern char *reencode_commit_message(const struct commit *commit,
|
||||
const char **encoding_p);
|
||||
extern void get_commit_format(const char *arg, struct rev_info *);
|
||||
extern const char *format_subject(struct strbuf *sb, const char *msg,
|
||||
const char *line_separator);
|
||||
extern void userformat_find_requirements(const char *fmt, struct userformat_want *w);
|
||||
extern void format_commit_message(const struct commit *commit,
|
||||
const char *format, struct strbuf *sb,
|
||||
const struct pretty_print_context *context);
|
||||
extern void pretty_print_commit(const struct pretty_print_context *pp,
|
||||
const struct commit *commit,
|
||||
struct strbuf *sb);
|
||||
extern void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,
|
||||
struct strbuf *sb);
|
||||
void pp_user_info(const struct pretty_print_context *pp,
|
||||
const char *what, struct strbuf *sb,
|
||||
const char *line, const char *encoding);
|
||||
void pp_title_line(const struct pretty_print_context *pp,
|
||||
const char **msg_p,
|
||||
struct strbuf *sb,
|
||||
const char *encoding,
|
||||
int need_8bit_cte);
|
||||
void pp_remainder(const struct pretty_print_context *pp,
|
||||
const char **msg_p,
|
||||
struct strbuf *sb,
|
||||
int indent);
|
||||
|
||||
|
||||
/** Removes the first commit from a list sorted by date, and adds all
|
||||
* of its parents.
|
||||
**/
|
||||
struct commit *pop_most_recent_commit(struct commit_list **list,
|
||||
unsigned int mark);
|
||||
|
||||
struct commit *pop_commit(struct commit_list **stack);
|
||||
|
||||
void clear_commit_marks(struct commit *commit, unsigned int mark);
|
||||
void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark);
|
||||
|
||||
/*
|
||||
* Performs an in-place topological sort of list supplied.
|
||||
*
|
||||
* invariant of resulting list is:
|
||||
* a reachable from b => ord(b) < ord(a)
|
||||
* in addition, when lifo == 0, commits on parallel tracks are
|
||||
* sorted in the dates order.
|
||||
*/
|
||||
void sort_in_topological_order(struct commit_list ** list, int lifo);
|
||||
|
||||
struct commit_graft {
|
||||
unsigned char sha1[20];
|
||||
int nr_parent; /* < 0 if shallow commit */
|
||||
unsigned char parent[FLEX_ARRAY][20]; /* more */
|
||||
};
|
||||
typedef int (*each_commit_graft_fn)(const struct commit_graft *, void *);
|
||||
|
||||
struct commit_graft *read_graft_line(char *buf, int len);
|
||||
int register_commit_graft(struct commit_graft *, int);
|
||||
struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
|
||||
|
||||
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
|
||||
extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
|
||||
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
|
||||
|
||||
extern int register_shallow(const unsigned char *sha1);
|
||||
extern int unregister_shallow(const unsigned char *sha1);
|
||||
extern int for_each_commit_graft(each_commit_graft_fn, void *);
|
||||
extern int is_repository_shallow(void);
|
||||
extern struct commit_list *get_shallow_commits(struct object_array *heads,
|
||||
int depth, int shallow_flag, int not_shallow_flag);
|
||||
|
||||
int is_descendant_of(struct commit *, struct commit_list *);
|
||||
int in_merge_bases(struct commit *, struct commit **, int);
|
||||
|
||||
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
|
||||
extern int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
const char **pathspec);
|
||||
|
||||
static inline int single_parent(struct commit *commit)
|
||||
{
|
||||
return commit->parents && !commit->parents->next;
|
||||
}
|
||||
|
||||
struct commit_list *reduce_heads(struct commit_list *heads);
|
||||
|
||||
struct commit_extra_header {
|
||||
struct commit_extra_header *next;
|
||||
char *key;
|
||||
char *value;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
extern void append_merge_tag_headers(struct commit_list *parents,
|
||||
struct commit_extra_header ***tail);
|
||||
|
||||
extern int commit_tree(const struct strbuf *msg, unsigned char *tree,
|
||||
struct commit_list *parents, unsigned char *ret,
|
||||
const char *author, const char *sign_commit);
|
||||
|
||||
extern int commit_tree_extended(const struct strbuf *msg, unsigned char *tree,
|
||||
struct commit_list *parents, unsigned char *ret,
|
||||
const char *author, const char *sign_commit,
|
||||
struct commit_extra_header *);
|
||||
|
||||
extern struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);
|
||||
extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
|
||||
|
||||
extern void free_commit_extra_headers(struct commit_extra_header *extra);
|
||||
|
||||
struct merge_remote_desc {
|
||||
struct object *obj; /* the named object, could be a tag */
|
||||
const char *name;
|
||||
};
|
||||
#define merge_remote_util(commit) ((struct merge_remote_desc *)((commit)->util))
|
||||
|
||||
/*
|
||||
* Given "name" from the command line to merge, find the commit object
|
||||
* and return it, while storing merge_remote_desc in its ->util field,
|
||||
* to allow callers to tell if we are told to merge a tag.
|
||||
*/
|
||||
struct commit *get_merge_parent(const char *name);
|
||||
|
||||
extern int parse_signed_commit(const unsigned char *sha1,
|
||||
struct strbuf *message, struct strbuf *signature);
|
||||
#endif /* COMMIT_H */
|
||||
725
test/fixtures/c/cpu.c
vendored
725
test/fixtures/c/cpu.c
vendored
@@ -1,725 +0,0 @@
|
||||
/* CPU control.
|
||||
* (C) 2001, 2002, 2003, 2004 Rusty Russell
|
||||
*
|
||||
* This code is licenced under the GPL.
|
||||
*/
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/oom.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "smpboot.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Serializes the updates to cpu_online_mask, cpu_present_mask */
|
||||
static DEFINE_MUTEX(cpu_add_remove_lock);
|
||||
|
||||
/*
|
||||
* The following two API's must be used when attempting
|
||||
* to serialize the updates to cpu_online_mask, cpu_present_mask.
|
||||
*/
|
||||
void cpu_maps_update_begin(void)
|
||||
{
|
||||
mutex_lock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
void cpu_maps_update_done(void)
|
||||
{
|
||||
mutex_unlock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
static RAW_NOTIFIER_HEAD(cpu_chain);
|
||||
|
||||
/* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
|
||||
* Should always be manipulated under cpu_add_remove_lock
|
||||
*/
|
||||
static int cpu_hotplug_disabled;
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
||||
static struct {
|
||||
struct task_struct *active_writer;
|
||||
struct mutex lock; /* Synchronizes accesses to refcount, */
|
||||
/*
|
||||
* Also blocks the new readers during
|
||||
* an ongoing cpu hotplug operation.
|
||||
*/
|
||||
int refcount;
|
||||
} cpu_hotplug = {
|
||||
.active_writer = NULL,
|
||||
.lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
|
||||
.refcount = 0,
|
||||
};
|
||||
|
||||
void get_online_cpus(void)
|
||||
{
|
||||
might_sleep();
|
||||
if (cpu_hotplug.active_writer == current)
|
||||
return;
|
||||
mutex_lock(&cpu_hotplug.lock);
|
||||
cpu_hotplug.refcount++;
|
||||
mutex_unlock(&cpu_hotplug.lock);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_online_cpus);
|
||||
|
||||
void put_online_cpus(void)
|
||||
{
|
||||
if (cpu_hotplug.active_writer == current)
|
||||
return;
|
||||
mutex_lock(&cpu_hotplug.lock);
|
||||
if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
|
||||
wake_up_process(cpu_hotplug.active_writer);
|
||||
mutex_unlock(&cpu_hotplug.lock);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(put_online_cpus);
|
||||
|
||||
/*
|
||||
* This ensures that the hotplug operation can begin only when the
|
||||
* refcount goes to zero.
|
||||
*
|
||||
* Note that during a cpu-hotplug operation, the new readers, if any,
|
||||
* will be blocked by the cpu_hotplug.lock
|
||||
*
|
||||
* Since cpu_hotplug_begin() is always called after invoking
|
||||
* cpu_maps_update_begin(), we can be sure that only one writer is active.
|
||||
*
|
||||
* Note that theoretically, there is a possibility of a livelock:
|
||||
* - Refcount goes to zero, last reader wakes up the sleeping
|
||||
* writer.
|
||||
* - Last reader unlocks the cpu_hotplug.lock.
|
||||
* - A new reader arrives at this moment, bumps up the refcount.
|
||||
* - The writer acquires the cpu_hotplug.lock finds the refcount
|
||||
* non zero and goes to sleep again.
|
||||
*
|
||||
* However, this is very difficult to achieve in practice since
|
||||
* get_online_cpus() not an api which is called all that often.
|
||||
*
|
||||
*/
|
||||
static void cpu_hotplug_begin(void)
|
||||
{
|
||||
cpu_hotplug.active_writer = current;
|
||||
|
||||
for (;;) {
|
||||
mutex_lock(&cpu_hotplug.lock);
|
||||
if (likely(!cpu_hotplug.refcount))
|
||||
break;
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
mutex_unlock(&cpu_hotplug.lock);
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_hotplug_done(void)
|
||||
{
|
||||
cpu_hotplug.active_writer = NULL;
|
||||
mutex_unlock(&cpu_hotplug.lock);
|
||||
}
|
||||
|
||||
#else /* #if CONFIG_HOTPLUG_CPU */
|
||||
static void cpu_hotplug_begin(void) {}
|
||||
static void cpu_hotplug_done(void) {}
|
||||
#endif /* #else #if CONFIG_HOTPLUG_CPU */
|
||||
|
||||
/* Need to know about CPUs going up/down? */
|
||||
int __ref register_cpu_notifier(struct notifier_block *nb)
|
||||
{
|
||||
int ret;
|
||||
cpu_maps_update_begin();
|
||||
ret = raw_notifier_chain_register(&cpu_chain, nb);
|
||||
cpu_maps_update_done();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __cpu_notify(unsigned long val, void *v, int nr_to_call,
|
||||
int *nr_calls)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call,
|
||||
nr_calls);
|
||||
|
||||
return notifier_to_errno(ret);
|
||||
}
|
||||
|
||||
static int cpu_notify(unsigned long val, void *v)
|
||||
{
|
||||
return __cpu_notify(val, v, -1, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
|
||||
static void cpu_notify_nofail(unsigned long val, void *v)
|
||||
{
|
||||
BUG_ON(cpu_notify(val, v));
|
||||
}
|
||||
EXPORT_SYMBOL(register_cpu_notifier);
|
||||
|
||||
void __ref unregister_cpu_notifier(struct notifier_block *nb)
|
||||
{
|
||||
cpu_maps_update_begin();
|
||||
raw_notifier_chain_unregister(&cpu_chain, nb);
|
||||
cpu_maps_update_done();
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_cpu_notifier);
|
||||
|
||||
/**
|
||||
* clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
|
||||
* @cpu: a CPU id
|
||||
*
|
||||
* This function walks all processes, finds a valid mm struct for each one and
|
||||
* then clears a corresponding bit in mm's cpumask. While this all sounds
|
||||
* trivial, there are various non-obvious corner cases, which this function
|
||||
* tries to solve in a safe manner.
|
||||
*
|
||||
* Also note that the function uses a somewhat relaxed locking scheme, so it may
|
||||
* be called only for an already offlined CPU.
|
||||
*/
|
||||
void clear_tasks_mm_cpumask(int cpu)
|
||||
{
|
||||
struct task_struct *p;
|
||||
|
||||
/*
|
||||
* This function is called after the cpu is taken down and marked
|
||||
* offline, so its not like new tasks will ever get this cpu set in
|
||||
* their mm mask. -- Peter Zijlstra
|
||||
* Thus, we may use rcu_read_lock() here, instead of grabbing
|
||||
* full-fledged tasklist_lock.
|
||||
*/
|
||||
WARN_ON(cpu_online(cpu));
|
||||
rcu_read_lock();
|
||||
for_each_process(p) {
|
||||
struct task_struct *t;
|
||||
|
||||
/*
|
||||
* Main thread might exit, but other threads may still have
|
||||
* a valid mm. Find one.
|
||||
*/
|
||||
t = find_lock_task_mm(p);
|
||||
if (!t)
|
||||
continue;
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
|
||||
task_unlock(t);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static inline void check_for_tasks(int cpu)
|
||||
{
|
||||
struct task_struct *p;
|
||||
|
||||
write_lock_irq(&tasklist_lock);
|
||||
for_each_process(p) {
|
||||
if (task_cpu(p) == cpu && p->state == TASK_RUNNING &&
|
||||
(p->utime || p->stime))
|
||||
printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d "
|
||||
"(state = %ld, flags = %x)\n",
|
||||
p->comm, task_pid_nr(p), cpu,
|
||||
p->state, p->flags);
|
||||
}
|
||||
write_unlock_irq(&tasklist_lock);
|
||||
}
|
||||
|
||||
struct take_cpu_down_param {
|
||||
unsigned long mod;
|
||||
void *hcpu;
|
||||
};
|
||||
|
||||
/* Take this CPU down. */
|
||||
static int __ref take_cpu_down(void *_param)
|
||||
{
|
||||
struct take_cpu_down_param *param = _param;
|
||||
int err;
|
||||
|
||||
/* Ensure this CPU doesn't handle any more interrupts. */
|
||||
err = __cpu_disable();
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cpu_notify(CPU_DYING | param->mod, param->hcpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Requires cpu_add_remove_lock to be held */
|
||||
static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
|
||||
{
|
||||
int err, nr_calls = 0;
|
||||
void *hcpu = (void *)(long)cpu;
|
||||
unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
|
||||
struct take_cpu_down_param tcd_param = {
|
||||
.mod = mod,
|
||||
.hcpu = hcpu,
|
||||
};
|
||||
|
||||
if (num_online_cpus() == 1)
|
||||
return -EBUSY;
|
||||
|
||||
if (!cpu_online(cpu))
|
||||
return -EINVAL;
|
||||
|
||||
cpu_hotplug_begin();
|
||||
|
||||
err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls);
|
||||
if (err) {
|
||||
nr_calls--;
|
||||
__cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL);
|
||||
printk("%s: attempt to take down CPU %u failed\n",
|
||||
__func__, cpu);
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
|
||||
if (err) {
|
||||
/* CPU didn't die: tell everyone. Can't complain. */
|
||||
cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
|
||||
|
||||
goto out_release;
|
||||
}
|
||||
BUG_ON(cpu_online(cpu));
|
||||
|
||||
/*
|
||||
* The migration_call() CPU_DYING callback will have removed all
|
||||
* runnable tasks from the cpu, there's only the idle task left now
|
||||
* that the migration thread is done doing the stop_machine thing.
|
||||
*
|
||||
* Wait for the stop thread to go away.
|
||||
*/
|
||||
while (!idle_cpu(cpu))
|
||||
cpu_relax();
|
||||
|
||||
/* This actually kills the CPU. */
|
||||
__cpu_die(cpu);
|
||||
|
||||
/* CPU is completely dead: tell everyone. Too late to complain. */
|
||||
cpu_notify_nofail(CPU_DEAD | mod, hcpu);
|
||||
|
||||
check_for_tasks(cpu);
|
||||
|
||||
out_release:
|
||||
cpu_hotplug_done();
|
||||
if (!err)
|
||||
cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu);
|
||||
return err;
|
||||
}
|
||||
|
||||
int __ref cpu_down(unsigned int cpu)
|
||||
{
|
||||
int err;
|
||||
|
||||
cpu_maps_update_begin();
|
||||
|
||||
if (cpu_hotplug_disabled) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = _cpu_down(cpu, 0);
|
||||
|
||||
out:
|
||||
cpu_maps_update_done();
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(cpu_down);
|
||||
#endif /*CONFIG_HOTPLUG_CPU*/
|
||||
|
||||
/* Requires cpu_add_remove_lock to be held */
|
||||
static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
|
||||
{
|
||||
int ret, nr_calls = 0;
|
||||
void *hcpu = (void *)(long)cpu;
|
||||
unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
|
||||
struct task_struct *idle;
|
||||
|
||||
if (cpu_online(cpu) || !cpu_present(cpu))
|
||||
return -EINVAL;
|
||||
|
||||
cpu_hotplug_begin();
|
||||
|
||||
idle = idle_thread_get(cpu);
|
||||
if (IS_ERR(idle)) {
|
||||
ret = PTR_ERR(idle);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
|
||||
if (ret) {
|
||||
nr_calls--;
|
||||
printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
|
||||
__func__, cpu);
|
||||
goto out_notify;
|
||||
}
|
||||
|
||||
/* Arch-specific enabling code. */
|
||||
ret = __cpu_up(cpu, idle);
|
||||
if (ret != 0)
|
||||
goto out_notify;
|
||||
BUG_ON(!cpu_online(cpu));
|
||||
|
||||
/* Now call notifier in preparation. */
|
||||
cpu_notify(CPU_ONLINE | mod, hcpu);
|
||||
|
||||
out_notify:
|
||||
if (ret != 0)
|
||||
__cpu_notify(CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);
|
||||
out:
|
||||
cpu_hotplug_done();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __cpuinit cpu_up(unsigned int cpu)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
int nid;
|
||||
pg_data_t *pgdat;
|
||||
#endif
|
||||
|
||||
if (!cpu_possible(cpu)) {
|
||||
printk(KERN_ERR "can't online cpu %d because it is not "
|
||||
"configured as may-hotadd at boot time\n", cpu);
|
||||
#if defined(CONFIG_IA64)
|
||||
printk(KERN_ERR "please check additional_cpus= boot "
|
||||
"parameter\n");
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
nid = cpu_to_node(cpu);
|
||||
if (!node_online(nid)) {
|
||||
err = mem_online_node(nid);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
pgdat = NODE_DATA(nid);
|
||||
if (!pgdat) {
|
||||
printk(KERN_ERR
|
||||
"Can't online cpu %d due to NULL pgdat\n", cpu);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (pgdat->node_zonelists->_zonerefs->zone == NULL) {
|
||||
mutex_lock(&zonelists_mutex);
|
||||
build_all_zonelists(NULL);
|
||||
mutex_unlock(&zonelists_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
cpu_maps_update_begin();
|
||||
|
||||
if (cpu_hotplug_disabled) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = _cpu_up(cpu, 0);
|
||||
|
||||
out:
|
||||
cpu_maps_update_done();
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_up);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP_SMP
|
||||
static cpumask_var_t frozen_cpus;
|
||||
|
||||
void __weak arch_disable_nonboot_cpus_begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __weak arch_disable_nonboot_cpus_end(void)
|
||||
{
|
||||
}
|
||||
|
||||
int disable_nonboot_cpus(void)
|
||||
{
|
||||
int cpu, first_cpu, error = 0;
|
||||
|
||||
cpu_maps_update_begin();
|
||||
first_cpu = cpumask_first(cpu_online_mask);
|
||||
/*
|
||||
* We take down all of the non-boot CPUs in one shot to avoid races
|
||||
* with the userspace trying to use the CPU hotplug at the same time
|
||||
*/
|
||||
cpumask_clear(frozen_cpus);
|
||||
arch_disable_nonboot_cpus_begin();
|
||||
|
||||
printk("Disabling non-boot CPUs ...\n");
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == first_cpu)
|
||||
continue;
|
||||
error = _cpu_down(cpu, 1);
|
||||
if (!error)
|
||||
cpumask_set_cpu(cpu, frozen_cpus);
|
||||
else {
|
||||
printk(KERN_ERR "Error taking CPU%d down: %d\n",
|
||||
cpu, error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
arch_disable_nonboot_cpus_end();
|
||||
|
||||
if (!error) {
|
||||
BUG_ON(num_online_cpus() > 1);
|
||||
/* Make sure the CPUs won't be enabled by someone else */
|
||||
cpu_hotplug_disabled = 1;
|
||||
} else {
|
||||
printk(KERN_ERR "Non-boot CPUs are not disabled\n");
|
||||
}
|
||||
cpu_maps_update_done();
|
||||
return error;
|
||||
}
|
||||
|
||||
void __weak arch_enable_nonboot_cpus_begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __weak arch_enable_nonboot_cpus_end(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __ref enable_nonboot_cpus(void)
|
||||
{
|
||||
int cpu, error;
|
||||
|
||||
/* Allow everyone to use the CPU hotplug again */
|
||||
cpu_maps_update_begin();
|
||||
cpu_hotplug_disabled = 0;
|
||||
if (cpumask_empty(frozen_cpus))
|
||||
goto out;
|
||||
|
||||
printk(KERN_INFO "Enabling non-boot CPUs ...\n");
|
||||
|
||||
arch_enable_nonboot_cpus_begin();
|
||||
|
||||
for_each_cpu(cpu, frozen_cpus) {
|
||||
error = _cpu_up(cpu, 1);
|
||||
if (!error) {
|
||||
printk(KERN_INFO "CPU%d is up\n", cpu);
|
||||
continue;
|
||||
}
|
||||
printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
|
||||
}
|
||||
|
||||
arch_enable_nonboot_cpus_end();
|
||||
|
||||
cpumask_clear(frozen_cpus);
|
||||
out:
|
||||
cpu_maps_update_done();
|
||||
}
|
||||
|
||||
static int __init alloc_frozen_cpus(void)
|
||||
{
|
||||
if (!alloc_cpumask_var(&frozen_cpus, GFP_KERNEL|__GFP_ZERO))
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
core_initcall(alloc_frozen_cpus);
|
||||
|
||||
/*
|
||||
* Prevent regular CPU hotplug from racing with the freezer, by disabling CPU
|
||||
* hotplug when tasks are about to be frozen. Also, don't allow the freezer
|
||||
* to continue until any currently running CPU hotplug operation gets
|
||||
* completed.
|
||||
* To modify the 'cpu_hotplug_disabled' flag, we need to acquire the
|
||||
* 'cpu_add_remove_lock'. And this same lock is also taken by the regular
|
||||
* CPU hotplug path and released only after it is complete. Thus, we
|
||||
* (and hence the freezer) will block here until any currently running CPU
|
||||
* hotplug operation gets completed.
|
||||
*/
|
||||
void cpu_hotplug_disable_before_freeze(void)
|
||||
{
|
||||
cpu_maps_update_begin();
|
||||
cpu_hotplug_disabled = 1;
|
||||
cpu_maps_update_done();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* When tasks have been thawed, re-enable regular CPU hotplug (which had been
|
||||
* disabled while beginning to freeze tasks).
|
||||
*/
|
||||
void cpu_hotplug_enable_after_thaw(void)
|
||||
{
|
||||
cpu_maps_update_begin();
|
||||
cpu_hotplug_disabled = 0;
|
||||
cpu_maps_update_done();
|
||||
}
|
||||
|
||||
/*
|
||||
* When callbacks for CPU hotplug notifications are being executed, we must
|
||||
* ensure that the state of the system with respect to the tasks being frozen
|
||||
* or not, as reported by the notification, remains unchanged *throughout the
|
||||
* duration* of the execution of the callbacks.
|
||||
* Hence we need to prevent the freezer from racing with regular CPU hotplug.
|
||||
*
|
||||
* This synchronization is implemented by mutually excluding regular CPU
|
||||
* hotplug and Suspend/Hibernate call paths by hooking onto the Suspend/
|
||||
* Hibernate notifications.
|
||||
*/
|
||||
static int
|
||||
cpu_hotplug_pm_callback(struct notifier_block *nb,
|
||||
unsigned long action, void *ptr)
|
||||
{
|
||||
switch (action) {
|
||||
|
||||
case PM_SUSPEND_PREPARE:
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
cpu_hotplug_disable_before_freeze();
|
||||
break;
|
||||
|
||||
case PM_POST_SUSPEND:
|
||||
case PM_POST_HIBERNATION:
|
||||
cpu_hotplug_enable_after_thaw();
|
||||
break;
|
||||
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
|
||||
static int __init cpu_hotplug_pm_sync_init(void)
|
||||
{
|
||||
pm_notifier(cpu_hotplug_pm_callback, 0);
|
||||
return 0;
|
||||
}
|
||||
core_initcall(cpu_hotplug_pm_sync_init);
|
||||
|
||||
#endif /* CONFIG_PM_SLEEP_SMP */
|
||||
|
||||
/**
|
||||
* notify_cpu_starting(cpu) - call the CPU_STARTING notifiers
|
||||
* @cpu: cpu that just started
|
||||
*
|
||||
* This function calls the cpu_chain notifiers with CPU_STARTING.
|
||||
* It must be called by the arch code on the new cpu, before the new cpu
|
||||
* enables interrupts and before the "boot" cpu returns from __cpu_up().
|
||||
*/
|
||||
void __cpuinit notify_cpu_starting(unsigned int cpu)
|
||||
{
|
||||
unsigned long val = CPU_STARTING;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP_SMP
|
||||
if (frozen_cpus != NULL && cpumask_test_cpu(cpu, frozen_cpus))
|
||||
val = CPU_STARTING_FROZEN;
|
||||
#endif /* CONFIG_PM_SLEEP_SMP */
|
||||
cpu_notify(val, (void *)(long)cpu);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/*
|
||||
* cpu_bit_bitmap[] is a special, "compressed" data structure that
|
||||
* represents all NR_CPUS bits binary values of 1<<nr.
|
||||
*
|
||||
* It is used by cpumask_of() to get a constant address to a CPU
|
||||
* mask value that has a single bit set only.
|
||||
*/
|
||||
|
||||
/* cpu_bit_bitmap[0] is empty - so we can back into it */
|
||||
#define MASK_DECLARE_1(x) [x+1][0] = (1UL << (x))
|
||||
#define MASK_DECLARE_2(x) MASK_DECLARE_1(x), MASK_DECLARE_1(x+1)
|
||||
#define MASK_DECLARE_4(x) MASK_DECLARE_2(x), MASK_DECLARE_2(x+2)
|
||||
#define MASK_DECLARE_8(x) MASK_DECLARE_4(x), MASK_DECLARE_4(x+4)
|
||||
|
||||
const unsigned long cpu_bit_bitmap[BITS_PER_LONG+1][BITS_TO_LONGS(NR_CPUS)] = {
|
||||
|
||||
MASK_DECLARE_8(0), MASK_DECLARE_8(8),
|
||||
MASK_DECLARE_8(16), MASK_DECLARE_8(24),
|
||||
#if BITS_PER_LONG > 32
|
||||
MASK_DECLARE_8(32), MASK_DECLARE_8(40),
|
||||
MASK_DECLARE_8(48), MASK_DECLARE_8(56),
|
||||
#endif
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cpu_bit_bitmap);
|
||||
|
||||
const DECLARE_BITMAP(cpu_all_bits, NR_CPUS) = CPU_BITS_ALL;
|
||||
EXPORT_SYMBOL(cpu_all_bits);
|
||||
|
||||
#ifdef CONFIG_INIT_ALL_POSSIBLE
|
||||
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
|
||||
= CPU_BITS_ALL;
|
||||
#else
|
||||
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
|
||||
#endif
|
||||
const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
|
||||
EXPORT_SYMBOL(cpu_possible_mask);
|
||||
|
||||
static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly;
|
||||
const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits);
|
||||
EXPORT_SYMBOL(cpu_online_mask);
|
||||
|
||||
static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly;
|
||||
const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits);
|
||||
EXPORT_SYMBOL(cpu_present_mask);
|
||||
|
||||
static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly;
|
||||
const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits);
|
||||
EXPORT_SYMBOL(cpu_active_mask);
|
||||
|
||||
void set_cpu_possible(unsigned int cpu, bool possible)
|
||||
{
|
||||
if (possible)
|
||||
cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits));
|
||||
else
|
||||
cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits));
|
||||
}
|
||||
|
||||
void set_cpu_present(unsigned int cpu, bool present)
|
||||
{
|
||||
if (present)
|
||||
cpumask_set_cpu(cpu, to_cpumask(cpu_present_bits));
|
||||
else
|
||||
cpumask_clear_cpu(cpu, to_cpumask(cpu_present_bits));
|
||||
}
|
||||
|
||||
void set_cpu_online(unsigned int cpu, bool online)
|
||||
{
|
||||
if (online)
|
||||
cpumask_set_cpu(cpu, to_cpumask(cpu_online_bits));
|
||||
else
|
||||
cpumask_clear_cpu(cpu, to_cpumask(cpu_online_bits));
|
||||
}
|
||||
|
||||
void set_cpu_active(unsigned int cpu, bool active)
|
||||
{
|
||||
if (active)
|
||||
cpumask_set_cpu(cpu, to_cpumask(cpu_active_bits));
|
||||
else
|
||||
cpumask_clear_cpu(cpu, to_cpumask(cpu_active_bits));
|
||||
}
|
||||
|
||||
void init_cpu_present(const struct cpumask *src)
|
||||
{
|
||||
cpumask_copy(to_cpumask(cpu_present_bits), src);
|
||||
}
|
||||
|
||||
void init_cpu_possible(const struct cpumask *src)
|
||||
{
|
||||
cpumask_copy(to_cpumask(cpu_possible_bits), src);
|
||||
}
|
||||
|
||||
void init_cpu_online(const struct cpumask *src)
|
||||
{
|
||||
cpumask_copy(to_cpumask(cpu_online_bits), src);
|
||||
}
|
||||
784
test/fixtures/c/diff.c
vendored
784
test/fixtures/c/diff.c
vendored
@@ -1,784 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 the libgit2 contributors
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "git2/diff.h"
|
||||
#include "diff.h"
|
||||
#include "fileops.h"
|
||||
#include "config.h"
|
||||
#include "attr_file.h"
|
||||
|
||||
static char *diff_prefix_from_pathspec(const git_strarray *pathspec)
|
||||
{
|
||||
git_buf prefix = GIT_BUF_INIT;
|
||||
const char *scan;
|
||||
|
||||
if (git_buf_common_prefix(&prefix, pathspec) < 0)
|
||||
return NULL;
|
||||
|
||||
/* diff prefix will only be leading non-wildcards */
|
||||
for (scan = prefix.ptr; *scan && !git__iswildcard(*scan); ++scan);
|
||||
git_buf_truncate(&prefix, scan - prefix.ptr);
|
||||
|
||||
if (prefix.size > 0)
|
||||
return git_buf_detach(&prefix);
|
||||
|
||||
git_buf_free(&prefix);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool diff_pathspec_is_interesting(const git_strarray *pathspec)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (pathspec == NULL || pathspec->count == 0)
|
||||
return false;
|
||||
if (pathspec->count > 1)
|
||||
return true;
|
||||
|
||||
str = pathspec->strings[0];
|
||||
if (!str || !str[0] || (!str[1] && (str[0] == '*' || str[0] == '.')))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool diff_path_matches_pathspec(git_diff_list *diff, const char *path)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_fnmatch *match;
|
||||
|
||||
if (!diff->pathspec.length)
|
||||
return true;
|
||||
|
||||
git_vector_foreach(&diff->pathspec, i, match) {
|
||||
int result = p_fnmatch(match->pattern, path, 0);
|
||||
|
||||
/* if we didn't match, look for exact dirname prefix match */
|
||||
if (result == FNM_NOMATCH &&
|
||||
(match->flags & GIT_ATTR_FNMATCH_HASWILD) == 0 &&
|
||||
strncmp(path, match->pattern, match->length) == 0 &&
|
||||
path[match->length] == '/')
|
||||
result = 0;
|
||||
|
||||
if (result == 0)
|
||||
return (match->flags & GIT_ATTR_FNMATCH_NEGATIVE) ? false : true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static git_diff_delta *diff_delta__alloc(
|
||||
git_diff_list *diff,
|
||||
git_delta_t status,
|
||||
const char *path)
|
||||
{
|
||||
git_diff_delta *delta = git__calloc(1, sizeof(git_diff_delta));
|
||||
if (!delta)
|
||||
return NULL;
|
||||
|
||||
delta->old_file.path = git_pool_strdup(&diff->pool, path);
|
||||
if (delta->old_file.path == NULL) {
|
||||
git__free(delta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
delta->new_file.path = delta->old_file.path;
|
||||
|
||||
if (diff->opts.flags & GIT_DIFF_REVERSE) {
|
||||
switch (status) {
|
||||
case GIT_DELTA_ADDED: status = GIT_DELTA_DELETED; break;
|
||||
case GIT_DELTA_DELETED: status = GIT_DELTA_ADDED; break;
|
||||
default: break; /* leave other status values alone */
|
||||
}
|
||||
}
|
||||
delta->status = status;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
static git_diff_delta *diff_delta__dup(
|
||||
const git_diff_delta *d, git_pool *pool)
|
||||
{
|
||||
git_diff_delta *delta = git__malloc(sizeof(git_diff_delta));
|
||||
if (!delta)
|
||||
return NULL;
|
||||
|
||||
memcpy(delta, d, sizeof(git_diff_delta));
|
||||
|
||||
delta->old_file.path = git_pool_strdup(pool, d->old_file.path);
|
||||
if (delta->old_file.path == NULL)
|
||||
goto fail;
|
||||
|
||||
if (d->new_file.path != d->old_file.path) {
|
||||
delta->new_file.path = git_pool_strdup(pool, d->new_file.path);
|
||||
if (delta->new_file.path == NULL)
|
||||
goto fail;
|
||||
} else {
|
||||
delta->new_file.path = delta->old_file.path;
|
||||
}
|
||||
|
||||
return delta;
|
||||
|
||||
fail:
|
||||
git__free(delta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static git_diff_delta *diff_delta__merge_like_cgit(
|
||||
const git_diff_delta *a, const git_diff_delta *b, git_pool *pool)
|
||||
{
|
||||
git_diff_delta *dup = diff_delta__dup(a, pool);
|
||||
if (!dup)
|
||||
return NULL;
|
||||
|
||||
if (git_oid_cmp(&dup->new_file.oid, &b->new_file.oid) == 0)
|
||||
return dup;
|
||||
|
||||
git_oid_cpy(&dup->new_file.oid, &b->new_file.oid);
|
||||
|
||||
dup->new_file.mode = b->new_file.mode;
|
||||
dup->new_file.size = b->new_file.size;
|
||||
dup->new_file.flags = b->new_file.flags;
|
||||
|
||||
/* Emulate C git for merging two diffs (a la 'git diff <sha>').
|
||||
*
|
||||
* When C git does a diff between the work dir and a tree, it actually
|
||||
* diffs with the index but uses the workdir contents. This emulates
|
||||
* those choices so we can emulate the type of diff.
|
||||
*/
|
||||
if (git_oid_cmp(&dup->old_file.oid, &dup->new_file.oid) == 0) {
|
||||
if (dup->status == GIT_DELTA_DELETED)
|
||||
/* preserve pending delete info */;
|
||||
else if (b->status == GIT_DELTA_UNTRACKED ||
|
||||
b->status == GIT_DELTA_IGNORED)
|
||||
dup->status = b->status;
|
||||
else
|
||||
dup->status = GIT_DELTA_UNMODIFIED;
|
||||
}
|
||||
else if (dup->status == GIT_DELTA_UNMODIFIED ||
|
||||
b->status == GIT_DELTA_DELETED)
|
||||
dup->status = b->status;
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
static int diff_delta__from_one(
|
||||
git_diff_list *diff,
|
||||
git_delta_t status,
|
||||
const git_index_entry *entry)
|
||||
{
|
||||
git_diff_delta *delta;
|
||||
|
||||
if (status == GIT_DELTA_IGNORED &&
|
||||
(diff->opts.flags & GIT_DIFF_INCLUDE_IGNORED) == 0)
|
||||
return 0;
|
||||
|
||||
if (status == GIT_DELTA_UNTRACKED &&
|
||||
(diff->opts.flags & GIT_DIFF_INCLUDE_UNTRACKED) == 0)
|
||||
return 0;
|
||||
|
||||
if (!diff_path_matches_pathspec(diff, entry->path))
|
||||
return 0;
|
||||
|
||||
delta = diff_delta__alloc(diff, status, entry->path);
|
||||
GITERR_CHECK_ALLOC(delta);
|
||||
|
||||
/* This fn is just for single-sided diffs */
|
||||
assert(status != GIT_DELTA_MODIFIED);
|
||||
|
||||
if (delta->status == GIT_DELTA_DELETED) {
|
||||
delta->old_file.mode = entry->mode;
|
||||
delta->old_file.size = entry->file_size;
|
||||
git_oid_cpy(&delta->old_file.oid, &entry->oid);
|
||||
} else /* ADDED, IGNORED, UNTRACKED */ {
|
||||
delta->new_file.mode = entry->mode;
|
||||
delta->new_file.size = entry->file_size;
|
||||
git_oid_cpy(&delta->new_file.oid, &entry->oid);
|
||||
}
|
||||
|
||||
delta->old_file.flags |= GIT_DIFF_FILE_VALID_OID;
|
||||
delta->new_file.flags |= GIT_DIFF_FILE_VALID_OID;
|
||||
|
||||
if (git_vector_insert(&diff->deltas, delta) < 0) {
|
||||
git__free(delta);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int diff_delta__from_two(
|
||||
git_diff_list *diff,
|
||||
git_delta_t status,
|
||||
const git_index_entry *old_entry,
|
||||
const git_index_entry *new_entry,
|
||||
git_oid *new_oid)
|
||||
{
|
||||
git_diff_delta *delta;
|
||||
|
||||
if (status == GIT_DELTA_UNMODIFIED &&
|
||||
(diff->opts.flags & GIT_DIFF_INCLUDE_UNMODIFIED) == 0)
|
||||
return 0;
|
||||
|
||||
if ((diff->opts.flags & GIT_DIFF_REVERSE) != 0) {
|
||||
const git_index_entry *temp = old_entry;
|
||||
old_entry = new_entry;
|
||||
new_entry = temp;
|
||||
}
|
||||
|
||||
delta = diff_delta__alloc(diff, status, old_entry->path);
|
||||
GITERR_CHECK_ALLOC(delta);
|
||||
|
||||
delta->old_file.mode = old_entry->mode;
|
||||
git_oid_cpy(&delta->old_file.oid, &old_entry->oid);
|
||||
delta->old_file.flags |= GIT_DIFF_FILE_VALID_OID;
|
||||
|
||||
delta->new_file.mode = new_entry->mode;
|
||||
git_oid_cpy(&delta->new_file.oid, new_oid ? new_oid : &new_entry->oid);
|
||||
if (new_oid || !git_oid_iszero(&new_entry->oid))
|
||||
delta->new_file.flags |= GIT_DIFF_FILE_VALID_OID;
|
||||
|
||||
if (git_vector_insert(&diff->deltas, delta) < 0) {
|
||||
git__free(delta);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *diff_strdup_prefix(git_pool *pool, const char *prefix)
|
||||
{
|
||||
size_t len = strlen(prefix);
|
||||
|
||||
/* append '/' at end if needed */
|
||||
if (len > 0 && prefix[len - 1] != '/')
|
||||
return git_pool_strcat(pool, prefix, "/");
|
||||
else
|
||||
return git_pool_strndup(pool, prefix, len + 1);
|
||||
}
|
||||
|
||||
static int diff_delta__cmp(const void *a, const void *b)
|
||||
{
|
||||
const git_diff_delta *da = a, *db = b;
|
||||
int val = strcmp(da->old_file.path, db->old_file.path);
|
||||
return val ? val : ((int)da->status - (int)db->status);
|
||||
}
|
||||
|
||||
static int config_bool(git_config *cfg, const char *name, int defvalue)
|
||||
{
|
||||
int val = defvalue;
|
||||
|
||||
if (git_config_get_bool(&val, cfg, name) < 0)
|
||||
giterr_clear();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static git_diff_list *git_diff_list_alloc(
|
||||
git_repository *repo, const git_diff_options *opts)
|
||||
{
|
||||
git_config *cfg;
|
||||
size_t i;
|
||||
git_diff_list *diff = git__calloc(1, sizeof(git_diff_list));
|
||||
if (diff == NULL)
|
||||
return NULL;
|
||||
|
||||
diff->repo = repo;
|
||||
|
||||
if (git_vector_init(&diff->deltas, 0, diff_delta__cmp) < 0 ||
|
||||
git_pool_init(&diff->pool, 1, 0) < 0)
|
||||
goto fail;
|
||||
|
||||
/* load config values that affect diff behavior */
|
||||
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
||||
goto fail;
|
||||
if (config_bool(cfg, "core.symlinks", 1))
|
||||
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
|
||||
if (config_bool(cfg, "core.ignorestat", 0))
|
||||
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_ASSUME_UNCHANGED;
|
||||
if (config_bool(cfg, "core.filemode", 1))
|
||||
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_EXEC_BIT;
|
||||
if (config_bool(cfg, "core.trustctime", 1))
|
||||
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_CTIME;
|
||||
/* Don't set GIT_DIFFCAPS_USE_DEV - compile time option in core git */
|
||||
|
||||
if (opts == NULL)
|
||||
return diff;
|
||||
|
||||
memcpy(&diff->opts, opts, sizeof(git_diff_options));
|
||||
memset(&diff->opts.pathspec, 0, sizeof(diff->opts.pathspec));
|
||||
|
||||
diff->opts.old_prefix = diff_strdup_prefix(&diff->pool,
|
||||
opts->old_prefix ? opts->old_prefix : DIFF_OLD_PREFIX_DEFAULT);
|
||||
diff->opts.new_prefix = diff_strdup_prefix(&diff->pool,
|
||||
opts->new_prefix ? opts->new_prefix : DIFF_NEW_PREFIX_DEFAULT);
|
||||
|
||||
if (!diff->opts.old_prefix || !diff->opts.new_prefix)
|
||||
goto fail;
|
||||
|
||||
if (diff->opts.flags & GIT_DIFF_REVERSE) {
|
||||
char *swap = diff->opts.old_prefix;
|
||||
diff->opts.old_prefix = diff->opts.new_prefix;
|
||||
diff->opts.new_prefix = swap;
|
||||
}
|
||||
|
||||
/* only copy pathspec if it is "interesting" so we can test
|
||||
* diff->pathspec.length > 0 to know if it is worth calling
|
||||
* fnmatch as we iterate.
|
||||
*/
|
||||
if (!diff_pathspec_is_interesting(&opts->pathspec))
|
||||
return diff;
|
||||
|
||||
if (git_vector_init(
|
||||
&diff->pathspec, (unsigned int)opts->pathspec.count, NULL) < 0)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < opts->pathspec.count; ++i) {
|
||||
int ret;
|
||||
const char *pattern = opts->pathspec.strings[i];
|
||||
git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
|
||||
if (!match)
|
||||
goto fail;
|
||||
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
||||
ret = git_attr_fnmatch__parse(match, &diff->pool, NULL, &pattern);
|
||||
if (ret == GIT_ENOTFOUND) {
|
||||
git__free(match);
|
||||
continue;
|
||||
} else if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (git_vector_insert(&diff->pathspec, match) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return diff;
|
||||
|
||||
fail:
|
||||
git_diff_list_free(diff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void git_diff_list_free(git_diff_list *diff)
|
||||
{
|
||||
git_diff_delta *delta;
|
||||
git_attr_fnmatch *match;
|
||||
unsigned int i;
|
||||
|
||||
if (!diff)
|
||||
return;
|
||||
|
||||
git_vector_foreach(&diff->deltas, i, delta) {
|
||||
git__free(delta);
|
||||
diff->deltas.contents[i] = NULL;
|
||||
}
|
||||
git_vector_free(&diff->deltas);
|
||||
|
||||
git_vector_foreach(&diff->pathspec, i, match) {
|
||||
git__free(match);
|
||||
diff->pathspec.contents[i] = NULL;
|
||||
}
|
||||
git_vector_free(&diff->pathspec);
|
||||
|
||||
git_pool_clear(&diff->pool);
|
||||
git__free(diff);
|
||||
}
|
||||
|
||||
static int oid_for_workdir_item(
|
||||
git_repository *repo,
|
||||
const git_index_entry *item,
|
||||
git_oid *oid)
|
||||
{
|
||||
int result;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
|
||||
if (git_buf_joinpath(&full_path, git_repository_workdir(repo), item->path) < 0)
|
||||
return -1;
|
||||
|
||||
/* calculate OID for file if possible*/
|
||||
if (S_ISLNK(item->mode))
|
||||
result = git_odb__hashlink(oid, full_path.ptr);
|
||||
else if (!git__is_sizet(item->file_size)) {
|
||||
giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
|
||||
result = -1;
|
||||
} else {
|
||||
int fd = git_futils_open_ro(full_path.ptr);
|
||||
if (fd < 0)
|
||||
result = fd;
|
||||
else {
|
||||
result = git_odb__hashfd(
|
||||
oid, fd, (size_t)item->file_size, GIT_OBJ_BLOB);
|
||||
p_close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
git_buf_free(&full_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define EXEC_BIT_MASK 0000111
|
||||
|
||||
static int maybe_modified(
|
||||
git_iterator *old_iter,
|
||||
const git_index_entry *oitem,
|
||||
git_iterator *new_iter,
|
||||
const git_index_entry *nitem,
|
||||
git_diff_list *diff)
|
||||
{
|
||||
git_oid noid, *use_noid = NULL;
|
||||
git_delta_t status = GIT_DELTA_MODIFIED;
|
||||
unsigned int omode = oitem->mode;
|
||||
unsigned int nmode = nitem->mode;
|
||||
|
||||
GIT_UNUSED(old_iter);
|
||||
|
||||
if (!diff_path_matches_pathspec(diff, oitem->path))
|
||||
return 0;
|
||||
|
||||
/* on platforms with no symlinks, promote plain files to symlinks */
|
||||
if (S_ISLNK(omode) && S_ISREG(nmode) &&
|
||||
!(diff->diffcaps & GIT_DIFFCAPS_HAS_SYMLINKS))
|
||||
nmode = GIT_MODE_TYPE(omode) | (nmode & GIT_MODE_PERMS_MASK);
|
||||
|
||||
/* on platforms with no execmode, clear exec bit from comparisons */
|
||||
if (!(diff->diffcaps & GIT_DIFFCAPS_TRUST_EXEC_BIT)) {
|
||||
omode = omode & ~EXEC_BIT_MASK;
|
||||
nmode = nmode & ~EXEC_BIT_MASK;
|
||||
}
|
||||
|
||||
/* support "assume unchanged" (badly, b/c we still stat everything) */
|
||||
if ((diff->diffcaps & GIT_DIFFCAPS_ASSUME_UNCHANGED) != 0)
|
||||
status = (oitem->flags_extended & GIT_IDXENTRY_INTENT_TO_ADD) ?
|
||||
GIT_DELTA_MODIFIED : GIT_DELTA_UNMODIFIED;
|
||||
|
||||
/* support "skip worktree" index bit */
|
||||
else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
|
||||
/* if basic type of file changed, then split into delete and add */
|
||||
else if (GIT_MODE_TYPE(omode) != GIT_MODE_TYPE(nmode)) {
|
||||
if (diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem) < 0 ||
|
||||
diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if oids and modes match, then file is unmodified */
|
||||
else if (git_oid_cmp(&oitem->oid, &nitem->oid) == 0 &&
|
||||
omode == nmode)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
|
||||
/* if we have a workdir item with an unknown oid, check deeper */
|
||||
else if (git_oid_iszero(&nitem->oid) && new_iter->type == GIT_ITERATOR_WORKDIR) {
|
||||
/* TODO: add check against index file st_mtime to avoid racy-git */
|
||||
|
||||
/* if they files look exactly alike, then we'll assume the same */
|
||||
if (oitem->file_size == nitem->file_size &&
|
||||
(!(diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) ||
|
||||
(oitem->ctime.seconds == nitem->ctime.seconds)) &&
|
||||
oitem->mtime.seconds == nitem->mtime.seconds &&
|
||||
(!(diff->diffcaps & GIT_DIFFCAPS_USE_DEV) ||
|
||||
(oitem->dev == nitem->dev)) &&
|
||||
oitem->ino == nitem->ino &&
|
||||
oitem->uid == nitem->uid &&
|
||||
oitem->gid == nitem->gid)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
|
||||
else if (S_ISGITLINK(nmode)) {
|
||||
git_submodule *sub;
|
||||
|
||||
if ((diff->opts.flags & GIT_DIFF_IGNORE_SUBMODULES) != 0)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
else if (git_submodule_lookup(&sub, diff->repo, nitem->path) < 0)
|
||||
return -1;
|
||||
else if (sub->ignore == GIT_SUBMODULE_IGNORE_ALL)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
else {
|
||||
/* TODO: support other GIT_SUBMODULE_IGNORE values */
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: check git attributes so we will not have to read the file
|
||||
* in if it is marked binary.
|
||||
*/
|
||||
|
||||
else if (oid_for_workdir_item(diff->repo, nitem, &noid) < 0)
|
||||
return -1;
|
||||
|
||||
else if (git_oid_cmp(&oitem->oid, &noid) == 0 &&
|
||||
omode == nmode)
|
||||
status = GIT_DELTA_UNMODIFIED;
|
||||
|
||||
/* store calculated oid so we don't have to recalc later */
|
||||
use_noid = &noid;
|
||||
}
|
||||
|
||||
return diff_delta__from_two(diff, status, oitem, nitem, use_noid);
|
||||
}
|
||||
|
||||
static int diff_from_iterators(
|
||||
git_repository *repo,
|
||||
const git_diff_options *opts, /**< can be NULL for defaults */
|
||||
git_iterator *old_iter,
|
||||
git_iterator *new_iter,
|
||||
git_diff_list **diff_ptr)
|
||||
{
|
||||
const git_index_entry *oitem, *nitem;
|
||||
git_buf ignore_prefix = GIT_BUF_INIT;
|
||||
git_diff_list *diff = git_diff_list_alloc(repo, opts);
|
||||
if (!diff)
|
||||
goto fail;
|
||||
|
||||
diff->old_src = old_iter->type;
|
||||
diff->new_src = new_iter->type;
|
||||
|
||||
if (git_iterator_current(old_iter, &oitem) < 0 ||
|
||||
git_iterator_current(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
|
||||
/* run iterators building diffs */
|
||||
while (oitem || nitem) {
|
||||
|
||||
/* create DELETED records for old items not matched in new */
|
||||
if (oitem && (!nitem || strcmp(oitem->path, nitem->path) < 0)) {
|
||||
if (diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem) < 0 ||
|
||||
git_iterator_advance(old_iter, &oitem) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create ADDED, TRACKED, or IGNORED records for new items not
|
||||
* matched in old (and/or descend into directories as needed)
|
||||
*/
|
||||
else if (nitem && (!oitem || strcmp(oitem->path, nitem->path) > 0)) {
|
||||
git_delta_t delta_type = GIT_DELTA_UNTRACKED;
|
||||
|
||||
/* check if contained in ignored parent directory */
|
||||
if (git_buf_len(&ignore_prefix) &&
|
||||
git__prefixcmp(nitem->path, git_buf_cstr(&ignore_prefix)) == 0)
|
||||
delta_type = GIT_DELTA_IGNORED;
|
||||
|
||||
if (S_ISDIR(nitem->mode)) {
|
||||
/* recurse into directory only if there are tracked items in
|
||||
* it or if the user requested the contents of untracked
|
||||
* directories and it is not under an ignored directory.
|
||||
*/
|
||||
if ((oitem && git__prefixcmp(oitem->path, nitem->path) == 0) ||
|
||||
(delta_type == GIT_DELTA_UNTRACKED &&
|
||||
(diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0))
|
||||
{
|
||||
/* if this directory is ignored, remember it as the
|
||||
* "ignore_prefix" for processing contained items
|
||||
*/
|
||||
if (delta_type == GIT_DELTA_UNTRACKED &&
|
||||
git_iterator_current_is_ignored(new_iter))
|
||||
git_buf_sets(&ignore_prefix, nitem->path);
|
||||
|
||||
if (git_iterator_advance_into_directory(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* In core git, the next two "else if" clauses are effectively
|
||||
* reversed -- i.e. when an untracked file contained in an
|
||||
* ignored directory is individually ignored, it shows up as an
|
||||
* ignored file in the diff list, even though other untracked
|
||||
* files in the same directory are skipped completely.
|
||||
*
|
||||
* To me, this is odd. If the directory is ignored and the file
|
||||
* is untracked, we should skip it consistently, regardless of
|
||||
* whether it happens to match a pattern in the ignore file.
|
||||
*
|
||||
* To match the core git behavior, just reverse the following
|
||||
* two "else if" cases so that individual file ignores are
|
||||
* checked before container directory exclusions are used to
|
||||
* skip the file.
|
||||
*/
|
||||
else if (delta_type == GIT_DELTA_IGNORED) {
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
continue; /* ignored parent directory, so skip completely */
|
||||
}
|
||||
|
||||
else if (git_iterator_current_is_ignored(new_iter))
|
||||
delta_type = GIT_DELTA_IGNORED;
|
||||
|
||||
else if (new_iter->type != GIT_ITERATOR_WORKDIR)
|
||||
delta_type = GIT_DELTA_ADDED;
|
||||
|
||||
if (diff_delta__from_one(diff, delta_type, nitem) < 0 ||
|
||||
git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* otherwise item paths match, so create MODIFIED record
|
||||
* (or ADDED and DELETED pair if type changed)
|
||||
*/
|
||||
else {
|
||||
assert(oitem && nitem && strcmp(oitem->path, nitem->path) == 0);
|
||||
|
||||
if (maybe_modified(old_iter, oitem, new_iter, nitem, diff) < 0 ||
|
||||
git_iterator_advance(old_iter, &oitem) < 0 ||
|
||||
git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
git_iterator_free(old_iter);
|
||||
git_iterator_free(new_iter);
|
||||
git_buf_free(&ignore_prefix);
|
||||
|
||||
*diff_ptr = diff;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
git_iterator_free(old_iter);
|
||||
git_iterator_free(new_iter);
|
||||
git_buf_free(&ignore_prefix);
|
||||
|
||||
git_diff_list_free(diff);
|
||||
*diff_ptr = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int git_diff_tree_to_tree(
|
||||
git_repository *repo,
|
||||
const git_diff_options *opts, /**< can be NULL for defaults */
|
||||
git_tree *old_tree,
|
||||
git_tree *new_tree,
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && old_tree && new_tree && diff);
|
||||
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_tree_range(&b, repo, new_tree, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
int git_diff_index_to_tree(
|
||||
git_repository *repo,
|
||||
const git_diff_options *opts,
|
||||
git_tree *old_tree,
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && diff);
|
||||
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_index_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
int git_diff_workdir_to_index(
|
||||
git_repository *repo,
|
||||
const git_diff_options *opts,
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && diff);
|
||||
|
||||
if (git_iterator_for_index_range(&a, repo, prefix, prefix) < 0 ||
|
||||
git_iterator_for_workdir_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
|
||||
int git_diff_workdir_to_tree(
|
||||
git_repository *repo,
|
||||
const git_diff_options *opts,
|
||||
git_tree *old_tree,
|
||||
git_diff_list **diff)
|
||||
{
|
||||
git_iterator *a = NULL, *b = NULL;
|
||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
||||
|
||||
assert(repo && old_tree && diff);
|
||||
|
||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
||||
git_iterator_for_workdir_range(&b, repo, prefix, prefix) < 0)
|
||||
return -1;
|
||||
|
||||
git__free(prefix);
|
||||
|
||||
return diff_from_iterators(repo, opts, a, b, diff);
|
||||
}
|
||||
|
||||
int git_diff_merge(
|
||||
git_diff_list *onto,
|
||||
const git_diff_list *from)
|
||||
{
|
||||
int error = 0;
|
||||
git_pool onto_pool;
|
||||
git_vector onto_new;
|
||||
git_diff_delta *delta;
|
||||
unsigned int i, j;
|
||||
|
||||
assert(onto && from);
|
||||
|
||||
if (!from->deltas.length)
|
||||
return 0;
|
||||
|
||||
if (git_vector_init(&onto_new, onto->deltas.length, diff_delta__cmp) < 0 ||
|
||||
git_pool_init(&onto_pool, 1, 0) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) {
|
||||
git_diff_delta *o = GIT_VECTOR_GET(&onto->deltas, i);
|
||||
const git_diff_delta *f = GIT_VECTOR_GET(&from->deltas, j);
|
||||
int cmp = !f ? -1 : !o ? 1 : strcmp(o->old_file.path, f->old_file.path);
|
||||
|
||||
if (cmp < 0) {
|
||||
delta = diff_delta__dup(o, &onto_pool);
|
||||
i++;
|
||||
} else if (cmp > 0) {
|
||||
delta = diff_delta__dup(f, &onto_pool);
|
||||
j++;
|
||||
} else {
|
||||
delta = diff_delta__merge_like_cgit(o, f, &onto_pool);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
if ((error = !delta ? -1 : git_vector_insert(&onto_new, delta)) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
git_vector_swap(&onto->deltas, &onto_new);
|
||||
git_pool_swap(&onto->pool, &onto_pool);
|
||||
onto->new_src = from->new_src;
|
||||
}
|
||||
|
||||
git_vector_foreach(&onto_new, i, delta)
|
||||
git__free(delta);
|
||||
git_vector_free(&onto_new);
|
||||
git_pool_clear(&onto_pool);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
609
test/fixtures/c/git.c
vendored
609
test/fixtures/c/git.c
vendored
@@ -1,609 +0,0 @@
|
||||
#include "builtin.h"
|
||||
#include "cache.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "help.h"
|
||||
#include "quote.h"
|
||||
#include "run-command.h"
|
||||
|
||||
const char git_usage_string[] =
|
||||
"git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
|
||||
" [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
|
||||
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
|
||||
" [-c name=value] [--help]\n"
|
||||
" <command> [<args>]";
|
||||
|
||||
const char git_more_info_string[] =
|
||||
N_("See 'git help <command>' for more information on a specific command.");
|
||||
|
||||
static struct startup_info git_startup_info;
|
||||
static int use_pager = -1;
|
||||
struct pager_config {
|
||||
const char *cmd;
|
||||
int want;
|
||||
char *value;
|
||||
};
|
||||
|
||||
static int pager_command_config(const char *var, const char *value, void *data)
|
||||
{
|
||||
struct pager_config *c = data;
|
||||
if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) {
|
||||
int b = git_config_maybe_bool(var, value);
|
||||
if (b >= 0)
|
||||
c->want = b;
|
||||
else {
|
||||
c->want = 1;
|
||||
c->value = xstrdup(value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
|
||||
int check_pager_config(const char *cmd)
|
||||
{
|
||||
struct pager_config c;
|
||||
c.cmd = cmd;
|
||||
c.want = -1;
|
||||
c.value = NULL;
|
||||
git_config(pager_command_config, &c);
|
||||
if (c.value)
|
||||
pager_program = c.value;
|
||||
return c.want;
|
||||
}
|
||||
|
||||
static void commit_pager_choice(void) {
|
||||
switch (use_pager) {
|
||||
case 0:
|
||||
setenv("GIT_PAGER", "cat", 1);
|
||||
break;
|
||||
case 1:
|
||||
setup_pager();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_options(const char ***argv, int *argc, int *envchanged)
|
||||
{
|
||||
const char **orig_argv = *argv;
|
||||
|
||||
while (*argc > 0) {
|
||||
const char *cmd = (*argv)[0];
|
||||
if (cmd[0] != '-')
|
||||
break;
|
||||
|
||||
/*
|
||||
* For legacy reasons, the "version" and "help"
|
||||
* commands can be written with "--" prepended
|
||||
* to make them look like flags.
|
||||
*/
|
||||
if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check remaining flags.
|
||||
*/
|
||||
if (!prefixcmp(cmd, "--exec-path")) {
|
||||
cmd += 11;
|
||||
if (*cmd == '=')
|
||||
git_set_argv_exec_path(cmd + 1);
|
||||
else {
|
||||
puts(git_exec_path());
|
||||
exit(0);
|
||||
}
|
||||
} else if (!strcmp(cmd, "--html-path")) {
|
||||
puts(system_path(GIT_HTML_PATH));
|
||||
exit(0);
|
||||
} else if (!strcmp(cmd, "--man-path")) {
|
||||
puts(system_path(GIT_MAN_PATH));
|
||||
exit(0);
|
||||
} else if (!strcmp(cmd, "--info-path")) {
|
||||
puts(system_path(GIT_INFO_PATH));
|
||||
exit(0);
|
||||
} else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
|
||||
use_pager = 1;
|
||||
} else if (!strcmp(cmd, "--no-pager")) {
|
||||
use_pager = 0;
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "--no-replace-objects")) {
|
||||
read_replace_refs = 0;
|
||||
setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "--git-dir")) {
|
||||
if (*argc < 2) {
|
||||
fprintf(stderr, "No directory given for --git-dir.\n" );
|
||||
usage(git_usage_string);
|
||||
}
|
||||
setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
} else if (!prefixcmp(cmd, "--git-dir=")) {
|
||||
setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "--namespace")) {
|
||||
if (*argc < 2) {
|
||||
fprintf(stderr, "No namespace given for --namespace.\n" );
|
||||
usage(git_usage_string);
|
||||
}
|
||||
setenv(GIT_NAMESPACE_ENVIRONMENT, (*argv)[1], 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
} else if (!prefixcmp(cmd, "--namespace=")) {
|
||||
setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "--work-tree")) {
|
||||
if (*argc < 2) {
|
||||
fprintf(stderr, "No directory given for --work-tree.\n" );
|
||||
usage(git_usage_string);
|
||||
}
|
||||
setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
} else if (!prefixcmp(cmd, "--work-tree=")) {
|
||||
setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "--bare")) {
|
||||
static char git_dir[PATH_MAX+1];
|
||||
is_bare_repository_cfg = 1;
|
||||
setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);
|
||||
if (envchanged)
|
||||
*envchanged = 1;
|
||||
} else if (!strcmp(cmd, "-c")) {
|
||||
if (*argc < 2) {
|
||||
fprintf(stderr, "-c expects a configuration string\n" );
|
||||
usage(git_usage_string);
|
||||
}
|
||||
git_config_push_parameter((*argv)[1]);
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown option: %s\n", cmd);
|
||||
usage(git_usage_string);
|
||||
}
|
||||
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
}
|
||||
return (*argv) - orig_argv;
|
||||
}
|
||||
|
||||
static int handle_alias(int *argcp, const char ***argv)
|
||||
{
|
||||
int envchanged = 0, ret = 0, saved_errno = errno;
|
||||
const char *subdir;
|
||||
int count, option_count;
|
||||
const char **new_argv;
|
||||
const char *alias_command;
|
||||
char *alias_string;
|
||||
int unused_nongit;
|
||||
|
||||
subdir = setup_git_directory_gently(&unused_nongit);
|
||||
|
||||
alias_command = (*argv)[0];
|
||||
alias_string = alias_lookup(alias_command);
|
||||
if (alias_string) {
|
||||
if (alias_string[0] == '!') {
|
||||
const char **alias_argv;
|
||||
int argc = *argcp, i;
|
||||
|
||||
commit_pager_choice();
|
||||
|
||||
/* build alias_argv */
|
||||
alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
|
||||
alias_argv[0] = alias_string + 1;
|
||||
for (i = 1; i < argc; ++i)
|
||||
alias_argv[i] = (*argv)[i];
|
||||
alias_argv[argc] = NULL;
|
||||
|
||||
ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
|
||||
if (ret >= 0) /* normal exit */
|
||||
exit(ret);
|
||||
|
||||
die_errno("While expanding alias '%s': '%s'",
|
||||
alias_command, alias_string + 1);
|
||||
}
|
||||
count = split_cmdline(alias_string, &new_argv);
|
||||
if (count < 0)
|
||||
die("Bad alias.%s string: %s", alias_command,
|
||||
split_cmdline_strerror(count));
|
||||
option_count = handle_options(&new_argv, &count, &envchanged);
|
||||
if (envchanged)
|
||||
die("alias '%s' changes environment variables\n"
|
||||
"You can use '!git' in the alias to do this.",
|
||||
alias_command);
|
||||
memmove(new_argv - option_count, new_argv,
|
||||
count * sizeof(char *));
|
||||
new_argv -= option_count;
|
||||
|
||||
if (count < 1)
|
||||
die("empty alias for %s", alias_command);
|
||||
|
||||
if (!strcmp(alias_command, new_argv[0]))
|
||||
die("recursive alias: %s", alias_command);
|
||||
|
||||
trace_argv_printf(new_argv,
|
||||
"trace: alias expansion: %s =>",
|
||||
alias_command);
|
||||
|
||||
new_argv = xrealloc(new_argv, sizeof(char *) *
|
||||
(count + *argcp));
|
||||
/* insert after command name */
|
||||
memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);
|
||||
|
||||
*argv = new_argv;
|
||||
*argcp += count - 1;
|
||||
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (subdir && chdir(subdir))
|
||||
die_errno("Cannot change to '%s'", subdir);
|
||||
|
||||
errno = saved_errno;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char git_version_string[] = GIT_VERSION;
|
||||
|
||||
#define RUN_SETUP (1<<0)
|
||||
#define RUN_SETUP_GENTLY (1<<1)
|
||||
#define USE_PAGER (1<<2)
|
||||
/*
|
||||
* require working tree to be present -- anything uses this needs
|
||||
* RUN_SETUP for reading from the configuration file.
|
||||
*/
|
||||
#define NEED_WORK_TREE (1<<3)
|
||||
|
||||
struct cmd_struct {
|
||||
const char *cmd;
|
||||
int (*fn)(int, const char **, const char *);
|
||||
int option;
|
||||
};
|
||||
|
||||
static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
||||
{
|
||||
int status, help;
|
||||
struct stat st;
|
||||
const char *prefix;
|
||||
|
||||
prefix = NULL;
|
||||
help = argc == 2 && !strcmp(argv[1], "-h");
|
||||
if (!help) {
|
||||
if (p->option & RUN_SETUP)
|
||||
prefix = setup_git_directory();
|
||||
if (p->option & RUN_SETUP_GENTLY) {
|
||||
int nongit_ok;
|
||||
prefix = setup_git_directory_gently(&nongit_ok);
|
||||
}
|
||||
|
||||
if (use_pager == -1 && p->option & (RUN_SETUP | RUN_SETUP_GENTLY))
|
||||
use_pager = check_pager_config(p->cmd);
|
||||
if (use_pager == -1 && p->option & USE_PAGER)
|
||||
use_pager = 1;
|
||||
|
||||
if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
|
||||
startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
|
||||
trace_repo_setup(prefix);
|
||||
}
|
||||
commit_pager_choice();
|
||||
|
||||
if (!help && p->option & NEED_WORK_TREE)
|
||||
setup_work_tree();
|
||||
|
||||
trace_argv_printf(argv, "trace: built-in: git");
|
||||
|
||||
status = p->fn(argc, argv, prefix);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Somebody closed stdout? */
|
||||
if (fstat(fileno(stdout), &st))
|
||||
return 0;
|
||||
/* Ignore write errors for pipes and sockets.. */
|
||||
if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode))
|
||||
return 0;
|
||||
|
||||
/* Check for ENOSPC and EIO errors.. */
|
||||
if (fflush(stdout))
|
||||
die_errno("write failure on standard output");
|
||||
if (ferror(stdout))
|
||||
die("unknown write failure on standard output");
|
||||
if (fclose(stdout))
|
||||
die_errno("close failed on standard output");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_internal_command(int argc, const char **argv)
|
||||
{
|
||||
const char *cmd = argv[0];
|
||||
static struct cmd_struct commands[] = {
|
||||
{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "annotate", cmd_annotate, RUN_SETUP },
|
||||
{ "apply", cmd_apply, RUN_SETUP_GENTLY },
|
||||
{ "archive", cmd_archive },
|
||||
{ "bisect--helper", cmd_bisect__helper, RUN_SETUP },
|
||||
{ "blame", cmd_blame, RUN_SETUP },
|
||||
{ "branch", cmd_branch, RUN_SETUP },
|
||||
{ "bundle", cmd_bundle, RUN_SETUP_GENTLY },
|
||||
{ "cat-file", cmd_cat_file, RUN_SETUP },
|
||||
{ "check-attr", cmd_check_attr, RUN_SETUP },
|
||||
{ "check-ref-format", cmd_check_ref_format },
|
||||
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "checkout-index", cmd_checkout_index,
|
||||
RUN_SETUP | NEED_WORK_TREE},
|
||||
{ "cherry", cmd_cherry, RUN_SETUP },
|
||||
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "clone", cmd_clone },
|
||||
{ "column", cmd_column, RUN_SETUP_GENTLY },
|
||||
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
|
||||
{ "config", cmd_config, RUN_SETUP_GENTLY },
|
||||
{ "count-objects", cmd_count_objects, RUN_SETUP },
|
||||
{ "describe", cmd_describe, RUN_SETUP },
|
||||
{ "diff", cmd_diff },
|
||||
{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "diff-index", cmd_diff_index, RUN_SETUP },
|
||||
{ "diff-tree", cmd_diff_tree, RUN_SETUP },
|
||||
{ "fast-export", cmd_fast_export, RUN_SETUP },
|
||||
{ "fetch", cmd_fetch, RUN_SETUP },
|
||||
{ "fetch-pack", cmd_fetch_pack, RUN_SETUP },
|
||||
{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
|
||||
{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
|
||||
{ "format-patch", cmd_format_patch, RUN_SETUP },
|
||||
{ "fsck", cmd_fsck, RUN_SETUP },
|
||||
{ "fsck-objects", cmd_fsck, RUN_SETUP },
|
||||
{ "gc", cmd_gc, RUN_SETUP },
|
||||
{ "get-tar-commit-id", cmd_get_tar_commit_id },
|
||||
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
|
||||
{ "hash-object", cmd_hash_object },
|
||||
{ "help", cmd_help },
|
||||
{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
|
||||
{ "init", cmd_init_db },
|
||||
{ "init-db", cmd_init_db },
|
||||
{ "log", cmd_log, RUN_SETUP },
|
||||
{ "ls-files", cmd_ls_files, RUN_SETUP },
|
||||
{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
|
||||
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
|
||||
{ "mailinfo", cmd_mailinfo },
|
||||
{ "mailsplit", cmd_mailsplit },
|
||||
{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "merge-base", cmd_merge_base, RUN_SETUP },
|
||||
{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
|
||||
{ "merge-index", cmd_merge_index, RUN_SETUP },
|
||||
{ "merge-ours", cmd_merge_ours, RUN_SETUP },
|
||||
{ "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "merge-tree", cmd_merge_tree, RUN_SETUP },
|
||||
{ "mktag", cmd_mktag, RUN_SETUP },
|
||||
{ "mktree", cmd_mktree, RUN_SETUP },
|
||||
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "name-rev", cmd_name_rev, RUN_SETUP },
|
||||
{ "notes", cmd_notes, RUN_SETUP },
|
||||
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
|
||||
{ "pack-redundant", cmd_pack_redundant, RUN_SETUP },
|
||||
{ "pack-refs", cmd_pack_refs, RUN_SETUP },
|
||||
{ "patch-id", cmd_patch_id },
|
||||
{ "peek-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
|
||||
{ "pickaxe", cmd_blame, RUN_SETUP },
|
||||
{ "prune", cmd_prune, RUN_SETUP },
|
||||
{ "prune-packed", cmd_prune_packed, RUN_SETUP },
|
||||
{ "push", cmd_push, RUN_SETUP },
|
||||
{ "read-tree", cmd_read_tree, RUN_SETUP },
|
||||
{ "receive-pack", cmd_receive_pack },
|
||||
{ "reflog", cmd_reflog, RUN_SETUP },
|
||||
{ "remote", cmd_remote, RUN_SETUP },
|
||||
{ "remote-ext", cmd_remote_ext },
|
||||
{ "remote-fd", cmd_remote_fd },
|
||||
{ "replace", cmd_replace, RUN_SETUP },
|
||||
{ "repo-config", cmd_repo_config, RUN_SETUP_GENTLY },
|
||||
{ "rerere", cmd_rerere, RUN_SETUP },
|
||||
{ "reset", cmd_reset, RUN_SETUP },
|
||||
{ "rev-list", cmd_rev_list, RUN_SETUP },
|
||||
{ "rev-parse", cmd_rev_parse },
|
||||
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "rm", cmd_rm, RUN_SETUP },
|
||||
{ "send-pack", cmd_send_pack, RUN_SETUP },
|
||||
{ "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
|
||||
{ "show", cmd_show, RUN_SETUP },
|
||||
{ "show-branch", cmd_show_branch, RUN_SETUP },
|
||||
{ "show-ref", cmd_show_ref, RUN_SETUP },
|
||||
{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
|
||||
{ "stripspace", cmd_stripspace },
|
||||
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
|
||||
{ "tag", cmd_tag, RUN_SETUP },
|
||||
{ "tar-tree", cmd_tar_tree },
|
||||
{ "unpack-file", cmd_unpack_file, RUN_SETUP },
|
||||
{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
|
||||
{ "update-index", cmd_update_index, RUN_SETUP },
|
||||
{ "update-ref", cmd_update_ref, RUN_SETUP },
|
||||
{ "update-server-info", cmd_update_server_info, RUN_SETUP },
|
||||
{ "upload-archive", cmd_upload_archive },
|
||||
{ "upload-archive--writer", cmd_upload_archive_writer },
|
||||
{ "var", cmd_var, RUN_SETUP_GENTLY },
|
||||
{ "verify-pack", cmd_verify_pack },
|
||||
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
|
||||
{ "version", cmd_version },
|
||||
{ "whatchanged", cmd_whatchanged, RUN_SETUP },
|
||||
{ "write-tree", cmd_write_tree, RUN_SETUP },
|
||||
};
|
||||
int i;
|
||||
static const char ext[] = STRIP_EXTENSION;
|
||||
|
||||
if (sizeof(ext) > 1) {
|
||||
i = strlen(argv[0]) - strlen(ext);
|
||||
if (i > 0 && !strcmp(argv[0] + i, ext)) {
|
||||
char *argv0 = xstrdup(argv[0]);
|
||||
argv[0] = cmd = argv0;
|
||||
argv0[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn "git cmd --help" into "git help cmd" */
|
||||
if (argc > 1 && !strcmp(argv[1], "--help")) {
|
||||
argv[1] = argv[0];
|
||||
argv[0] = cmd = "help";
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
||||
struct cmd_struct *p = commands+i;
|
||||
if (strcmp(p->cmd, cmd))
|
||||
continue;
|
||||
exit(run_builtin(p, argc, argv));
|
||||
}
|
||||
}
|
||||
|
||||
static void execv_dashed_external(const char **argv)
|
||||
{
|
||||
struct strbuf cmd = STRBUF_INIT;
|
||||
const char *tmp;
|
||||
int status;
|
||||
|
||||
if (use_pager == -1)
|
||||
use_pager = check_pager_config(argv[0]);
|
||||
commit_pager_choice();
|
||||
|
||||
strbuf_addf(&cmd, "git-%s", argv[0]);
|
||||
|
||||
/*
|
||||
* argv[0] must be the git command, but the argv array
|
||||
* belongs to the caller, and may be reused in
|
||||
* subsequent loop iterations. Save argv[0] and
|
||||
* restore it on error.
|
||||
*/
|
||||
tmp = argv[0];
|
||||
argv[0] = cmd.buf;
|
||||
|
||||
trace_argv_printf(argv, "trace: exec:");
|
||||
|
||||
/*
|
||||
* if we fail because the command is not found, it is
|
||||
* OK to return. Otherwise, we just pass along the status code.
|
||||
*/
|
||||
status = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE | RUN_CLEAN_ON_EXIT);
|
||||
if (status >= 0 || errno != ENOENT)
|
||||
exit(status);
|
||||
|
||||
argv[0] = tmp;
|
||||
|
||||
strbuf_release(&cmd);
|
||||
}
|
||||
|
||||
static int run_argv(int *argcp, const char ***argv)
|
||||
{
|
||||
int done_alias = 0;
|
||||
|
||||
while (1) {
|
||||
/* See if it's an internal command */
|
||||
handle_internal_command(*argcp, *argv);
|
||||
|
||||
/* .. then try the external ones */
|
||||
execv_dashed_external(*argv);
|
||||
|
||||
/* It could be an alias -- this works around the insanity
|
||||
* of overriding "git log" with "git show" by having
|
||||
* alias.log = show
|
||||
*/
|
||||
if (done_alias || !handle_alias(argcp, argv))
|
||||
break;
|
||||
done_alias = 1;
|
||||
}
|
||||
|
||||
return done_alias;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
const char *cmd;
|
||||
|
||||
startup_info = &git_startup_info;
|
||||
|
||||
cmd = git_extract_argv0_path(argv[0]);
|
||||
if (!cmd)
|
||||
cmd = "git-help";
|
||||
|
||||
git_setup_gettext();
|
||||
|
||||
/*
|
||||
* "git-xxxx" is the same as "git xxxx", but we obviously:
|
||||
*
|
||||
* - cannot take flags in between the "git" and the "xxxx".
|
||||
* - cannot execute it externally (since it would just do
|
||||
* the same thing over again)
|
||||
*
|
||||
* So we just directly call the internal command handler, and
|
||||
* die if that one cannot handle it.
|
||||
*/
|
||||
if (!prefixcmp(cmd, "git-")) {
|
||||
cmd += 4;
|
||||
argv[0] = cmd;
|
||||
handle_internal_command(argc, argv);
|
||||
die("cannot handle %s internally", cmd);
|
||||
}
|
||||
|
||||
/* Look for flags.. */
|
||||
argv++;
|
||||
argc--;
|
||||
handle_options(&argv, &argc, NULL);
|
||||
if (argc > 0) {
|
||||
if (!prefixcmp(argv[0], "--"))
|
||||
argv[0] += 2;
|
||||
} else {
|
||||
/* The user didn't specify a command; give them help */
|
||||
commit_pager_choice();
|
||||
printf("usage: %s\n\n", git_usage_string);
|
||||
list_common_cmds_help();
|
||||
printf("\n%s\n", git_more_info_string);
|
||||
exit(1);
|
||||
}
|
||||
cmd = argv[0];
|
||||
|
||||
/*
|
||||
* We use PATH to find git commands, but we prepend some higher
|
||||
* precedence paths: the "--exec-path" option, the GIT_EXEC_PATH
|
||||
* environment, and the $(gitexecdir) from the Makefile at build
|
||||
* time.
|
||||
*/
|
||||
setup_path();
|
||||
|
||||
while (1) {
|
||||
static int done_help = 0;
|
||||
static int was_alias = 0;
|
||||
was_alias = run_argv(&argc, &argv);
|
||||
if (errno != ENOENT)
|
||||
break;
|
||||
if (was_alias) {
|
||||
fprintf(stderr, "Expansion of alias '%s' failed; "
|
||||
"'%s' is not a git command\n",
|
||||
cmd, argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (!done_help) {
|
||||
cmd = argv[0] = help_unknown_cmd(cmd);
|
||||
done_help = 1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to run command '%s': %s\n",
|
||||
cmd, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
74
test/fixtures/c/hash.c
vendored
74
test/fixtures/c/hash.c
vendored
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "hash.h"
|
||||
|
||||
#if defined(PPC_SHA1)
|
||||
# include "ppc/sha1.h"
|
||||
#else
|
||||
# include "sha1.h"
|
||||
#endif
|
||||
|
||||
struct git_hash_ctx {
|
||||
SHA_CTX c;
|
||||
};
|
||||
|
||||
git_hash_ctx *git_hash_new_ctx(void)
|
||||
{
|
||||
git_hash_ctx *ctx = git__malloc(sizeof(*ctx));
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
SHA1_Init(&ctx->c);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void git_hash_free_ctx(git_hash_ctx *ctx)
|
||||
{
|
||||
git__free(ctx);
|
||||
}
|
||||
|
||||
void git_hash_init(git_hash_ctx *ctx)
|
||||
{
|
||||
assert(ctx);
|
||||
SHA1_Init(&ctx->c);
|
||||
}
|
||||
|
||||
void git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
|
||||
{
|
||||
assert(ctx);
|
||||
SHA1_Update(&ctx->c, data, len);
|
||||
}
|
||||
|
||||
void git_hash_final(git_oid *out, git_hash_ctx *ctx)
|
||||
{
|
||||
assert(ctx);
|
||||
SHA1_Final(out->id, &ctx->c);
|
||||
}
|
||||
|
||||
void git_hash_buf(git_oid *out, const void *data, size_t len)
|
||||
{
|
||||
SHA_CTX c;
|
||||
|
||||
SHA1_Init(&c);
|
||||
SHA1_Update(&c, data, len);
|
||||
SHA1_Final(out->id, &c);
|
||||
}
|
||||
|
||||
void git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n)
|
||||
{
|
||||
SHA_CTX c;
|
||||
size_t i;
|
||||
|
||||
SHA1_Init(&c);
|
||||
for (i = 0; i < n; i++)
|
||||
SHA1_Update(&c, vec[i].data, vec[i].len);
|
||||
SHA1_Final(out->id, &c);
|
||||
}
|
||||
7
test/fixtures/c/hello.c
vendored
7
test/fixtures/c/hello.c
vendored
@@ -1,7 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World\n");
|
||||
return 0;
|
||||
}
|
||||
6
test/fixtures/c/hello.h
vendored
6
test/fixtures/c/hello.h
vendored
@@ -1,6 +0,0 @@
|
||||
#ifndef HELLO_H
|
||||
#define HELLO_H
|
||||
|
||||
void hello();
|
||||
|
||||
#endif
|
||||
2059
test/fixtures/c/http_parser.c
vendored
2059
test/fixtures/c/http_parser.c
vendored
File diff suppressed because it is too large
Load Diff
318
test/fixtures/c/http_parser.h
vendored
318
test/fixtures/c/http_parser.h
vendored
@@ -1,318 +0,0 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef http_parser_h
|
||||
#define http_parser_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HTTP_PARSER_VERSION_MAJOR 1
|
||||
#define HTTP_PARSER_VERSION_MINOR 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
typedef unsigned int size_t;
|
||||
typedef int ssize_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
|
||||
* faster
|
||||
*/
|
||||
#ifndef HTTP_PARSER_STRICT
|
||||
# define HTTP_PARSER_STRICT 1
|
||||
#endif
|
||||
|
||||
/* Compile with -DHTTP_PARSER_DEBUG=1 to add extra debugging information to
|
||||
* the error reporting facility.
|
||||
*/
|
||||
#ifndef HTTP_PARSER_DEBUG
|
||||
# define HTTP_PARSER_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
/* Maximium header size allowed */
|
||||
#define HTTP_MAX_HEADER_SIZE (80*1024)
|
||||
|
||||
|
||||
typedef struct http_parser http_parser;
|
||||
typedef struct http_parser_settings http_parser_settings;
|
||||
|
||||
|
||||
/* Callbacks should return non-zero to indicate an error. The parser will
|
||||
* then halt execution.
|
||||
*
|
||||
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
|
||||
* returning '1' from on_headers_complete will tell the parser that it
|
||||
* should not expect a body. This is used when receiving a response to a
|
||||
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
||||
* chunked' headers that indicate the presence of a body.
|
||||
*
|
||||
* http_data_cb does not return data chunks. It will be call arbitrarally
|
||||
* many times for each string. E.G. you might get 10 callbacks for "on_path"
|
||||
* each providing just a few characters more data.
|
||||
*/
|
||||
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
|
||||
typedef int (*http_cb) (http_parser*);
|
||||
|
||||
|
||||
/* Request Methods */
|
||||
#define HTTP_METHOD_MAP(XX) \
|
||||
XX(0, DELETE, DELETE) \
|
||||
XX(1, GET, GET) \
|
||||
XX(2, HEAD, HEAD) \
|
||||
XX(3, POST, POST) \
|
||||
XX(4, PUT, PUT) \
|
||||
/* pathological */ \
|
||||
XX(5, CONNECT, CONNECT) \
|
||||
XX(6, OPTIONS, OPTIONS) \
|
||||
XX(7, TRACE, TRACE) \
|
||||
/* webdav */ \
|
||||
XX(8, COPY, COPY) \
|
||||
XX(9, LOCK, LOCK) \
|
||||
XX(10, MKCOL, MKCOL) \
|
||||
XX(11, MOVE, MOVE) \
|
||||
XX(12, PROPFIND, PROPFIND) \
|
||||
XX(13, PROPPATCH, PROPPATCH) \
|
||||
XX(14, SEARCH, SEARCH) \
|
||||
XX(15, UNLOCK, UNLOCK) \
|
||||
/* subversion */ \
|
||||
XX(16, REPORT, REPORT) \
|
||||
XX(17, MKACTIVITY, MKACTIVITY) \
|
||||
XX(18, CHECKOUT, CHECKOUT) \
|
||||
XX(19, MERGE, MERGE) \
|
||||
/* upnp */ \
|
||||
XX(20, MSEARCH, M-SEARCH) \
|
||||
XX(21, NOTIFY, NOTIFY) \
|
||||
XX(22, SUBSCRIBE, SUBSCRIBE) \
|
||||
XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \
|
||||
/* RFC-5789 */ \
|
||||
XX(24, PATCH, PATCH) \
|
||||
XX(25, PURGE, PURGE) \
|
||||
|
||||
enum http_method
|
||||
{
|
||||
#define XX(num, name, string) HTTP_##name = num,
|
||||
HTTP_METHOD_MAP(XX)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
|
||||
|
||||
|
||||
/* Flag values for http_parser.flags field */
|
||||
enum flags
|
||||
{ F_CHUNKED = 1 << 0
|
||||
, F_CONNECTION_KEEP_ALIVE = 1 << 1
|
||||
, F_CONNECTION_CLOSE = 1 << 2
|
||||
, F_TRAILING = 1 << 3
|
||||
, F_UPGRADE = 1 << 4
|
||||
, F_SKIPBODY = 1 << 5
|
||||
};
|
||||
|
||||
|
||||
/* Map for errno-related constants
|
||||
*
|
||||
* The provided argument should be a macro that takes 2 arguments.
|
||||
*/
|
||||
#define HTTP_ERRNO_MAP(XX) \
|
||||
/* No error */ \
|
||||
XX(OK, "success") \
|
||||
\
|
||||
/* Callback-related errors */ \
|
||||
XX(CB_message_begin, "the on_message_begin callback failed") \
|
||||
XX(CB_url, "the on_url callback failed") \
|
||||
XX(CB_header_field, "the on_header_field callback failed") \
|
||||
XX(CB_header_value, "the on_header_value callback failed") \
|
||||
XX(CB_headers_complete, "the on_headers_complete callback failed") \
|
||||
XX(CB_body, "the on_body callback failed") \
|
||||
XX(CB_message_complete, "the on_message_complete callback failed") \
|
||||
\
|
||||
/* Parsing-related errors */ \
|
||||
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
|
||||
XX(HEADER_OVERFLOW, \
|
||||
"too many header bytes seen; overflow detected") \
|
||||
XX(CLOSED_CONNECTION, \
|
||||
"data received after completed connection: close message") \
|
||||
XX(INVALID_VERSION, "invalid HTTP version") \
|
||||
XX(INVALID_STATUS, "invalid HTTP status code") \
|
||||
XX(INVALID_METHOD, "invalid HTTP method") \
|
||||
XX(INVALID_URL, "invalid URL") \
|
||||
XX(INVALID_HOST, "invalid host") \
|
||||
XX(INVALID_PORT, "invalid port") \
|
||||
XX(INVALID_PATH, "invalid path") \
|
||||
XX(INVALID_QUERY_STRING, "invalid query string") \
|
||||
XX(INVALID_FRAGMENT, "invalid fragment") \
|
||||
XX(LF_EXPECTED, "LF character expected") \
|
||||
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
|
||||
XX(INVALID_CONTENT_LENGTH, \
|
||||
"invalid character in content-length header") \
|
||||
XX(INVALID_CHUNK_SIZE, \
|
||||
"invalid character in chunk size header") \
|
||||
XX(INVALID_CONSTANT, "invalid constant string") \
|
||||
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
|
||||
XX(STRICT, "strict mode assertion failed") \
|
||||
XX(PAUSED, "parser is paused") \
|
||||
XX(UNKNOWN, "an unknown error occurred")
|
||||
|
||||
|
||||
/* Define HPE_* values for each errno value above */
|
||||
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
|
||||
enum http_errno {
|
||||
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
|
||||
};
|
||||
#undef HTTP_ERRNO_GEN
|
||||
|
||||
|
||||
/* Get an http_errno value from an http_parser */
|
||||
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
|
||||
|
||||
/* Get the line number that generated the current error */
|
||||
#if HTTP_PARSER_DEBUG
|
||||
#define HTTP_PARSER_ERRNO_LINE(p) ((p)->error_lineno)
|
||||
#else
|
||||
#define HTTP_PARSER_ERRNO_LINE(p) 0
|
||||
#endif
|
||||
|
||||
|
||||
struct http_parser {
|
||||
/** PRIVATE **/
|
||||
unsigned char type : 2; /* enum http_parser_type */
|
||||
unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */
|
||||
unsigned char state; /* enum state from http_parser.c */
|
||||
unsigned char header_state; /* enum header_state from http_parser.c */
|
||||
unsigned char index; /* index into current matcher */
|
||||
|
||||
uint32_t nread; /* # bytes read in various scenarios */
|
||||
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
|
||||
|
||||
/** READ-ONLY **/
|
||||
unsigned short http_major;
|
||||
unsigned short http_minor;
|
||||
unsigned short status_code; /* responses only */
|
||||
unsigned char method; /* requests only */
|
||||
unsigned char http_errno : 7;
|
||||
|
||||
/* 1 = Upgrade header was present and the parser has exited because of that.
|
||||
* 0 = No upgrade header present.
|
||||
* Should be checked when http_parser_execute() returns in addition to
|
||||
* error checking.
|
||||
*/
|
||||
unsigned char upgrade : 1;
|
||||
|
||||
#if HTTP_PARSER_DEBUG
|
||||
uint32_t error_lineno;
|
||||
#endif
|
||||
|
||||
/** PUBLIC **/
|
||||
void *data; /* A pointer to get hook to the "connection" or "socket" object */
|
||||
};
|
||||
|
||||
|
||||
struct http_parser_settings {
|
||||
http_cb on_message_begin;
|
||||
http_data_cb on_url;
|
||||
http_data_cb on_header_field;
|
||||
http_data_cb on_header_value;
|
||||
http_cb on_headers_complete;
|
||||
http_data_cb on_body;
|
||||
http_cb on_message_complete;
|
||||
};
|
||||
|
||||
|
||||
enum http_parser_url_fields
|
||||
{ UF_SCHEMA = 0
|
||||
, UF_HOST = 1
|
||||
, UF_PORT = 2
|
||||
, UF_PATH = 3
|
||||
, UF_QUERY = 4
|
||||
, UF_FRAGMENT = 5
|
||||
, UF_MAX = 6
|
||||
};
|
||||
|
||||
|
||||
/* Result structure for http_parser_parse_url().
|
||||
*
|
||||
* Callers should index into field_data[] with UF_* values iff field_set
|
||||
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
|
||||
* because we probably have padding left over), we convert any port to
|
||||
* a uint16_t.
|
||||
*/
|
||||
struct http_parser_url {
|
||||
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
|
||||
uint16_t port; /* Converted UF_PORT string */
|
||||
|
||||
struct {
|
||||
uint16_t off; /* Offset into buffer in which field starts */
|
||||
uint16_t len; /* Length of run in buffer */
|
||||
} field_data[UF_MAX];
|
||||
};
|
||||
|
||||
|
||||
void http_parser_init(http_parser *parser, enum http_parser_type type);
|
||||
|
||||
|
||||
size_t http_parser_execute(http_parser *parser,
|
||||
const http_parser_settings *settings,
|
||||
const char *data,
|
||||
size_t len);
|
||||
|
||||
|
||||
/* If http_should_keep_alive() in the on_headers_complete or
|
||||
* on_message_complete callback returns true, then this will be should be
|
||||
* the last message on the connection.
|
||||
* If you are the server, respond with the "Connection: close" header.
|
||||
* If you are the client, close the connection.
|
||||
*/
|
||||
int http_should_keep_alive(http_parser *parser);
|
||||
|
||||
/* Returns a string version of the HTTP method. */
|
||||
const char *http_method_str(enum http_method m);
|
||||
|
||||
/* Return a string name of the given error */
|
||||
const char *http_errno_name(enum http_errno err);
|
||||
|
||||
/* Return a string description of the given error */
|
||||
const char *http_errno_description(enum http_errno err);
|
||||
|
||||
/* Parse a URL; return nonzero on failure */
|
||||
int http_parser_parse_url(const char *buf, size_t buflen,
|
||||
int is_connect,
|
||||
struct http_parser_url *u);
|
||||
|
||||
/* Pause or un-pause the parser; a nonzero value pauses */
|
||||
void http_parser_pause(http_parser *parser, int paused);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
2551
test/fixtures/c/markdown.c
vendored
2551
test/fixtures/c/markdown.c
vendored
File diff suppressed because it is too large
Load Diff
462
test/fixtures/c/process.c
vendored
462
test/fixtures/c/process.c
vendored
@@ -1,462 +0,0 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && !TARGET_OS_IPHONE
|
||||
# include <crt_externs.h>
|
||||
# define environ (*_NSGetEnviron())
|
||||
#else
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
|
||||
static void uv__chld(EV_P_ ev_child* watcher, int revents) {
|
||||
int status = watcher->rstatus;
|
||||
int exit_status = 0;
|
||||
int term_signal = 0;
|
||||
uv_process_t *process = watcher->data;
|
||||
|
||||
assert(&process->child_watcher == watcher);
|
||||
assert(revents & EV_CHILD);
|
||||
|
||||
ev_child_stop(EV_A_ &process->child_watcher);
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
exit_status = WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
term_signal = WTERMSIG(status);
|
||||
}
|
||||
|
||||
if (process->exit_cb) {
|
||||
process->exit_cb(process, exit_status, term_signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv__make_socketpair(int fds[2], int flags) {
|
||||
#ifdef SOCK_NONBLOCK
|
||||
int fl;
|
||||
|
||||
fl = SOCK_CLOEXEC;
|
||||
|
||||
if (flags & UV__F_NONBLOCK)
|
||||
fl |= SOCK_NONBLOCK;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM|fl, 0, fds) == 0)
|
||||
return 0;
|
||||
|
||||
if (errno != EINVAL)
|
||||
return -1;
|
||||
|
||||
/* errno == EINVAL so maybe the kernel headers lied about
|
||||
* the availability of SOCK_NONBLOCK. This can happen if people
|
||||
* build libuv against newer kernel headers than the kernel
|
||||
* they actually run the software on.
|
||||
*/
|
||||
#endif
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
||||
return -1;
|
||||
|
||||
uv__cloexec(fds[0], 1);
|
||||
uv__cloexec(fds[1], 1);
|
||||
|
||||
if (flags & UV__F_NONBLOCK) {
|
||||
uv__nonblock(fds[0], 1);
|
||||
uv__nonblock(fds[1], 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__make_pipe(int fds[2], int flags) {
|
||||
#if __linux__
|
||||
int fl;
|
||||
|
||||
fl = UV__O_CLOEXEC;
|
||||
|
||||
if (flags & UV__F_NONBLOCK)
|
||||
fl |= UV__O_NONBLOCK;
|
||||
|
||||
if (uv__pipe2(fds, fl) == 0)
|
||||
return 0;
|
||||
|
||||
if (errno != ENOSYS)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (pipe(fds))
|
||||
return -1;
|
||||
|
||||
uv__cloexec(fds[0], 1);
|
||||
uv__cloexec(fds[1], 1);
|
||||
|
||||
if (flags & UV__F_NONBLOCK) {
|
||||
uv__nonblock(fds[0], 1);
|
||||
uv__nonblock(fds[1], 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Used for initializing stdio streams like options.stdin_stream. Returns
|
||||
* zero on success.
|
||||
*/
|
||||
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
|
||||
int writable) {
|
||||
int fd = -1;
|
||||
switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
|
||||
UV_INHERIT_STREAM)) {
|
||||
case UV_IGNORE:
|
||||
return 0;
|
||||
case UV_CREATE_PIPE:
|
||||
assert(container->data.stream != NULL);
|
||||
|
||||
if (container->data.stream->type != UV_NAMED_PIPE) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return uv__make_socketpair(fds, 0);
|
||||
case UV_INHERIT_FD:
|
||||
case UV_INHERIT_STREAM:
|
||||
if (container->flags & UV_INHERIT_FD) {
|
||||
fd = container->data.fd;
|
||||
} else {
|
||||
fd = container->data.stream->fd;
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fds[writable ? 1 : 0] = fd;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
assert(0 && "Unexpected flags");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int uv__process_stdio_flags(uv_stdio_container_t* container,
|
||||
int writable) {
|
||||
if (container->data.stream->type == UV_NAMED_PIPE &&
|
||||
((uv_pipe_t*)container->data.stream)->ipc) {
|
||||
return UV_STREAM_READABLE | UV_STREAM_WRITABLE;
|
||||
} else if (writable) {
|
||||
return UV_STREAM_WRITABLE;
|
||||
} else {
|
||||
return UV_STREAM_READABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
|
||||
int writable) {
|
||||
int fd = fds[writable ? 1 : 0];
|
||||
int child_fd = fds[writable ? 0 : 1];
|
||||
int flags;
|
||||
|
||||
/* No need to create stream */
|
||||
if (!(container->flags & UV_CREATE_PIPE) || fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(child_fd >= 0);
|
||||
close(child_fd);
|
||||
|
||||
uv__nonblock(fd, 1);
|
||||
flags = uv__process_stdio_flags(container, writable);
|
||||
|
||||
return uv__stream_open((uv_stream_t*)container->data.stream, fd, flags);
|
||||
}
|
||||
|
||||
|
||||
static void uv__process_close_stream(uv_stdio_container_t* container) {
|
||||
if (!(container->flags & UV_CREATE_PIPE)) return;
|
||||
|
||||
uv__stream_close((uv_stream_t*)container->data.stream);
|
||||
}
|
||||
|
||||
|
||||
static void uv__process_child_init(uv_process_options_t options,
|
||||
int stdio_count,
|
||||
int* pipes) {
|
||||
int i;
|
||||
|
||||
if (options.flags & UV_PROCESS_DETACHED) {
|
||||
setsid();
|
||||
}
|
||||
|
||||
/* Dup fds */
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
/*
|
||||
* stdin has swapped ends of pipe
|
||||
* (it's the only one readable stream)
|
||||
*/
|
||||
int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2];
|
||||
int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1];
|
||||
|
||||
if (use_fd >= 0) {
|
||||
close(close_fd);
|
||||
} else if (i < 3) {
|
||||
/* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */
|
||||
use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR);
|
||||
|
||||
if (use_fd < 0) {
|
||||
perror("failed to open stdio");
|
||||
_exit(127);
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i != use_fd) {
|
||||
dup2(use_fd, i);
|
||||
close(use_fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.cwd && chdir(options.cwd)) {
|
||||
perror("chdir()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
|
||||
perror("setgid()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
|
||||
perror("setuid()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
environ = options.env;
|
||||
|
||||
execvp(options.file, options.args);
|
||||
perror("execvp()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SPAWN_WAIT_EXEC
|
||||
# define SPAWN_WAIT_EXEC 1
|
||||
#endif
|
||||
|
||||
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
||||
uv_process_options_t options) {
|
||||
/*
|
||||
* Save environ in the case that we get it clobbered
|
||||
* by the child process.
|
||||
*/
|
||||
char** save_our_env = environ;
|
||||
|
||||
int stdio_count = options.stdio_count < 3 ? 3 : options.stdio_count;
|
||||
int* pipes = malloc(2 * stdio_count * sizeof(int));
|
||||
|
||||
#if SPAWN_WAIT_EXEC
|
||||
int signal_pipe[2] = { -1, -1 };
|
||||
struct pollfd pfd;
|
||||
#endif
|
||||
int status;
|
||||
pid_t pid;
|
||||
int i;
|
||||
|
||||
if (pipes == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
assert(options.file != NULL);
|
||||
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
|
||||
UV_PROCESS_DETACHED |
|
||||
UV_PROCESS_SETGID |
|
||||
UV_PROCESS_SETUID)));
|
||||
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
||||
loop->counters.process_init++;
|
||||
uv__handle_start(process);
|
||||
|
||||
process->exit_cb = options.exit_cb;
|
||||
|
||||
/* Init pipe pairs */
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
pipes[i * 2] = -1;
|
||||
pipes[i * 2 + 1] = -1;
|
||||
}
|
||||
|
||||
/* Create socketpairs/pipes, or use raw fd */
|
||||
for (i = 0; i < options.stdio_count; i++) {
|
||||
if (uv__process_init_stdio(&options.stdio[i], pipes + i * 2, i != 0)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* This pipe is used by the parent to wait until
|
||||
* the child has called `execve()`. We need this
|
||||
* to avoid the following race condition:
|
||||
*
|
||||
* if ((pid = fork()) > 0) {
|
||||
* kill(pid, SIGTERM);
|
||||
* }
|
||||
* else if (pid == 0) {
|
||||
* execve("/bin/cat", argp, envp);
|
||||
* }
|
||||
*
|
||||
* The parent sends a signal immediately after forking.
|
||||
* Since the child may not have called `execve()` yet,
|
||||
* there is no telling what process receives the signal,
|
||||
* our fork or /bin/cat.
|
||||
*
|
||||
* To avoid ambiguity, we create a pipe with both ends
|
||||
* marked close-on-exec. Then, after the call to `fork()`,
|
||||
* the parent polls the read end until it sees POLLHUP.
|
||||
*/
|
||||
#if SPAWN_WAIT_EXEC
|
||||
if (uv__make_pipe(signal_pipe, UV__F_NONBLOCK))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
#if SPAWN_WAIT_EXEC
|
||||
close(signal_pipe[0]);
|
||||
close(signal_pipe[1]);
|
||||
#endif
|
||||
environ = save_our_env;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* Child */
|
||||
uv__process_child_init(options, stdio_count, pipes);
|
||||
|
||||
/* Execution never reaches here. */
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
/* Restore environment. */
|
||||
environ = save_our_env;
|
||||
|
||||
#if SPAWN_WAIT_EXEC
|
||||
/* POLLHUP signals child has exited or execve()'d. */
|
||||
close(signal_pipe[1]);
|
||||
do {
|
||||
pfd.fd = signal_pipe[0];
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
pfd.revents = 0;
|
||||
errno = 0, status = poll(&pfd, 1, -1);
|
||||
}
|
||||
while (status == -1 && (errno == EINTR || errno == ENOMEM));
|
||||
|
||||
assert((status == 1) && "poll() on pipe read end failed");
|
||||
close(signal_pipe[0]);
|
||||
#endif
|
||||
|
||||
process->pid = pid;
|
||||
|
||||
ev_child_init(&process->child_watcher, uv__chld, pid, 0);
|
||||
ev_child_start(process->loop->ev, &process->child_watcher);
|
||||
process->child_watcher.data = process;
|
||||
|
||||
for (i = 0; i < options.stdio_count; i++) {
|
||||
if (uv__process_open_stream(&options.stdio[i], pipes + i * 2, i == 0)) {
|
||||
int j;
|
||||
/* Close all opened streams */
|
||||
for (j = 0; j < i; j++) {
|
||||
uv__process_close_stream(&options.stdio[j]);
|
||||
}
|
||||
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
free(pipes);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
uv__set_sys_error(process->loop, errno);
|
||||
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
close(pipes[i * 2]);
|
||||
close(pipes[i * 2 + 1]);
|
||||
}
|
||||
|
||||
free(pipes);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int uv_process_kill(uv_process_t* process, int signum) {
|
||||
int r = kill(process->pid, signum);
|
||||
|
||||
if (r) {
|
||||
uv__set_sys_error(process->loop, errno);
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_kill(int pid, int signum) {
|
||||
int r = kill(pid, signum);
|
||||
|
||||
if (r) {
|
||||
return uv__new_sys_error(errno);
|
||||
} else {
|
||||
return uv_ok_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__process_close(uv_process_t* handle) {
|
||||
ev_child_stop(handle->loop->ev, &handle->child_watcher);
|
||||
uv__handle_stop(handle);
|
||||
}
|
||||
129
test/fixtures/c/rdiscount.c
vendored
129
test/fixtures/c/rdiscount.c
vendored
@@ -1,129 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "ruby.h"
|
||||
#include "mkdio.h"
|
||||
|
||||
static VALUE rb_cRDiscount;
|
||||
|
||||
static VALUE
|
||||
rb_rdiscount_to_html(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
/* grab char pointer to markdown input text */
|
||||
char *res;
|
||||
int szres;
|
||||
VALUE encoding;
|
||||
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
||||
VALUE buf = rb_str_buf_new(1024);
|
||||
Check_Type(text, T_STRING);
|
||||
|
||||
int flags = rb_rdiscount__get_flags(self);
|
||||
|
||||
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
||||
|
||||
if ( mkd_compile(doc, flags) ) {
|
||||
szres = mkd_document(doc, &res);
|
||||
|
||||
if ( szres != EOF ) {
|
||||
rb_str_cat(buf, res, szres);
|
||||
rb_str_cat(buf, "\n", 1);
|
||||
}
|
||||
}
|
||||
mkd_cleanup(doc);
|
||||
|
||||
|
||||
/* force the input encoding */
|
||||
if ( rb_respond_to(text, rb_intern("encoding")) ) {
|
||||
encoding = rb_funcall(text, rb_intern("encoding"), 0);
|
||||
rb_funcall(buf, rb_intern("force_encoding"), 1, encoding);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_rdiscount_toc_content(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
char *res;
|
||||
int szres;
|
||||
|
||||
int flags = rb_rdiscount__get_flags(self);
|
||||
|
||||
/* grab char pointer to markdown input text */
|
||||
VALUE text = rb_funcall(self, rb_intern("text"), 0);
|
||||
Check_Type(text, T_STRING);
|
||||
|
||||
/* allocate a ruby string buffer and wrap it in a stream */
|
||||
VALUE buf = rb_str_buf_new(4096);
|
||||
|
||||
MMIOT *doc = mkd_string(RSTRING_PTR(text), RSTRING_LEN(text), flags);
|
||||
|
||||
if ( mkd_compile(doc, flags) ) {
|
||||
szres = mkd_toc(doc, &res);
|
||||
|
||||
if ( szres != EOF ) {
|
||||
rb_str_cat(buf, res, szres);
|
||||
rb_str_cat(buf, "\n", 1);
|
||||
}
|
||||
}
|
||||
mkd_cleanup(doc);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int rb_rdiscount__get_flags(VALUE ruby_obj)
|
||||
{
|
||||
/* compile flags */
|
||||
int flags = MKD_TABSTOP | MKD_NOHEADER;
|
||||
|
||||
/* smart */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("smart"), 0) != Qtrue )
|
||||
flags = flags | MKD_NOPANTS;
|
||||
|
||||
/* filter_html */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("filter_html"), 0) == Qtrue )
|
||||
flags = flags | MKD_NOHTML;
|
||||
|
||||
/* generate_toc */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("generate_toc"), 0) == Qtrue)
|
||||
flags = flags | MKD_TOC;
|
||||
|
||||
/* no_image */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("no_image"), 0) == Qtrue)
|
||||
flags = flags | MKD_NOIMAGE;
|
||||
|
||||
/* no_links */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("no_links"), 0) == Qtrue)
|
||||
flags = flags | MKD_NOLINKS;
|
||||
|
||||
/* no_tables */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("no_tables"), 0) == Qtrue)
|
||||
flags = flags | MKD_NOTABLES;
|
||||
|
||||
/* strict */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("strict"), 0) == Qtrue)
|
||||
flags = flags | MKD_STRICT;
|
||||
|
||||
/* autolink */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("autolink"), 0) == Qtrue)
|
||||
flags = flags | MKD_AUTOLINK;
|
||||
|
||||
/* safelink */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("safelink"), 0) == Qtrue)
|
||||
flags = flags | MKD_SAFELINK;
|
||||
|
||||
/* no_pseudo_protocols */
|
||||
if ( rb_funcall(ruby_obj, rb_intern("no_pseudo_protocols"), 0) == Qtrue)
|
||||
flags = flags | MKD_NO_EXT;
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
void Init_rdiscount()
|
||||
{
|
||||
rb_cRDiscount = rb_define_class("RDiscount", rb_cObject);
|
||||
rb_define_method(rb_cRDiscount, "to_html", rb_rdiscount_to_html, -1);
|
||||
rb_define_method(rb_cRDiscount, "toc_content", rb_rdiscount_toc_content, -1);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4: */
|
||||
2538
test/fixtures/c/redis.c
vendored
2538
test/fixtures/c/redis.c
vendored
File diff suppressed because it is too large
Load Diff
164
test/fixtures/c/yajl.c
vendored
164
test/fixtures/c/yajl.c
vendored
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, Lloyd Hilaiel.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. Neither the name of Lloyd Hilaiel nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "api/yajl_parse.h"
|
||||
#include "yajl_lex.h"
|
||||
#include "yajl_parser.h"
|
||||
#include "yajl_alloc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
const char *
|
||||
yajl_status_to_string(yajl_status stat)
|
||||
{
|
||||
const char * statStr = "unknown";
|
||||
switch (stat) {
|
||||
case yajl_status_ok:
|
||||
statStr = "ok, no error";
|
||||
break;
|
||||
case yajl_status_client_canceled:
|
||||
statStr = "client canceled parse";
|
||||
break;
|
||||
case yajl_status_insufficient_data:
|
||||
statStr = "eof was met before the parse could complete";
|
||||
break;
|
||||
case yajl_status_error:
|
||||
statStr = "parse error";
|
||||
break;
|
||||
}
|
||||
return statStr;
|
||||
}
|
||||
|
||||
yajl_handle
|
||||
yajl_alloc(const yajl_callbacks * callbacks,
|
||||
const yajl_parser_config * config,
|
||||
const yajl_alloc_funcs * afs,
|
||||
void * ctx)
|
||||
{
|
||||
unsigned int allowComments = 0;
|
||||
unsigned int validateUTF8 = 0;
|
||||
yajl_handle hand = NULL;
|
||||
yajl_alloc_funcs afsBuffer;
|
||||
|
||||
/* first order of business is to set up memory allocation routines */
|
||||
if (afs != NULL) {
|
||||
if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
yajl_set_default_alloc_funcs(&afsBuffer);
|
||||
afs = &afsBuffer;
|
||||
}
|
||||
|
||||
hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
|
||||
|
||||
/* copy in pointers to allocation routines */
|
||||
memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
|
||||
|
||||
if (config != NULL) {
|
||||
allowComments = config->allowComments;
|
||||
validateUTF8 = config->checkUTF8;
|
||||
}
|
||||
|
||||
hand->callbacks = callbacks;
|
||||
hand->ctx = ctx;
|
||||
hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
|
||||
hand->bytesConsumed = 0;
|
||||
hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
|
||||
yajl_bs_init(hand->stateStack, &(hand->alloc));
|
||||
|
||||
yajl_bs_push(hand->stateStack, yajl_state_start);
|
||||
|
||||
return hand;
|
||||
}
|
||||
|
||||
void
|
||||
yajl_reset_parser(yajl_handle hand) {
|
||||
hand->lexer = yajl_lex_realloc(hand->lexer);
|
||||
}
|
||||
|
||||
void
|
||||
yajl_free(yajl_handle handle)
|
||||
{
|
||||
yajl_bs_free(handle->stateStack);
|
||||
yajl_buf_free(handle->decodeBuf);
|
||||
yajl_lex_free(handle->lexer);
|
||||
YA_FREE(&(handle->alloc), handle);
|
||||
}
|
||||
|
||||
yajl_status
|
||||
yajl_parse(yajl_handle hand, const unsigned char * jsonText,
|
||||
unsigned int jsonTextLen)
|
||||
{
|
||||
yajl_status status;
|
||||
status = yajl_do_parse(hand, jsonText, jsonTextLen);
|
||||
return status;
|
||||
}
|
||||
|
||||
yajl_status
|
||||
yajl_parse_complete(yajl_handle hand)
|
||||
{
|
||||
/* The particular case we want to handle is a trailing number.
|
||||
* Further input consisting of digits could cause our interpretation
|
||||
* of the number to change (buffered "1" but "2" comes in).
|
||||
* A very simple approach to this is to inject whitespace to terminate
|
||||
* any number in the lex buffer.
|
||||
*/
|
||||
return yajl_parse(hand, (const unsigned char *)" ", 1);
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
yajl_get_error(yajl_handle hand, int verbose,
|
||||
const unsigned char * jsonText, unsigned int jsonTextLen)
|
||||
{
|
||||
return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
yajl_get_bytes_consumed(yajl_handle hand)
|
||||
{
|
||||
if (!hand) return 0;
|
||||
else return hand->bytesConsumed;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
yajl_free_error(yajl_handle hand, unsigned char * str)
|
||||
{
|
||||
/* use memory allocation functions if set */
|
||||
YA_FREE(&(hand->alloc), str);
|
||||
}
|
||||
|
||||
/* XXX: add utility routines to parse from file */
|
||||
55
test/fixtures/coffee/browser.coffee
vendored
55
test/fixtures/coffee/browser.coffee
vendored
@@ -1,55 +0,0 @@
|
||||
# Override exported methods for non-Node.js engines.
|
||||
|
||||
CoffeeScript = require './coffee-script'
|
||||
CoffeeScript.require = require
|
||||
|
||||
# Use standard JavaScript `eval` to eval code.
|
||||
CoffeeScript.eval = (code, options = {}) ->
|
||||
options.bare ?= on
|
||||
eval CoffeeScript.compile code, options
|
||||
|
||||
# Running code does not provide access to this scope.
|
||||
CoffeeScript.run = (code, options = {}) ->
|
||||
options.bare = on
|
||||
Function(CoffeeScript.compile code, options)()
|
||||
|
||||
# If we're not in a browser environment, we're finished with the public API.
|
||||
return unless window?
|
||||
|
||||
# Load a remote script from the current domain via XHR.
|
||||
CoffeeScript.load = (url, callback) ->
|
||||
xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP')
|
||||
xhr.open 'GET', url, true
|
||||
xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr
|
||||
xhr.onreadystatechange = ->
|
||||
if xhr.readyState is 4
|
||||
if xhr.status in [0, 200]
|
||||
CoffeeScript.run xhr.responseText
|
||||
else
|
||||
throw new Error "Could not load #{url}"
|
||||
callback() if callback
|
||||
xhr.send null
|
||||
|
||||
# Activate CoffeeScript in the browser by having it compile and evaluate
|
||||
# all script tags with a content-type of `text/coffeescript`.
|
||||
# This happens on page load.
|
||||
runScripts = ->
|
||||
scripts = document.getElementsByTagName 'script'
|
||||
coffees = (s for s in scripts when s.type is 'text/coffeescript')
|
||||
index = 0
|
||||
length = coffees.length
|
||||
do execute = ->
|
||||
script = coffees[index++]
|
||||
if script?.type is 'text/coffeescript'
|
||||
if script.src
|
||||
CoffeeScript.load script.src, execute
|
||||
else
|
||||
CoffeeScript.run script.innerHTML
|
||||
execute()
|
||||
null
|
||||
|
||||
# Listen for window load, both in browsers and in IE.
|
||||
if window.addEventListener
|
||||
addEventListener 'DOMContentLoaded', runScripts, no
|
||||
else
|
||||
attachEvent 'onload', runScripts
|
||||
21
test/fixtures/coffee/classes.coffee
vendored
21
test/fixtures/coffee/classes.coffee
vendored
@@ -1,21 +0,0 @@
|
||||
class Animal
|
||||
constructor: (@name) ->
|
||||
|
||||
move: (meters) ->
|
||||
alert @name + " moved " + meters + "m."
|
||||
|
||||
class Snake extends Animal
|
||||
move: ->
|
||||
alert "Slithering..."
|
||||
super 5
|
||||
|
||||
class Horse extends Animal
|
||||
move: ->
|
||||
alert "Galloping..."
|
||||
super 45
|
||||
|
||||
sam = new Snake "Sammy the Python"
|
||||
tom = new Horse "Tommy the Palomino"
|
||||
|
||||
sam.move()
|
||||
tom.move()
|
||||
130
test/fixtures/coffee/coffee-script.coffee
vendored
130
test/fixtures/coffee/coffee-script.coffee
vendored
@@ -1,130 +0,0 @@
|
||||
# CoffeeScript can be used both on the server, as a command-line compiler based
|
||||
# on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
|
||||
# contains the main entry functions for tokenizing, parsing, and compiling
|
||||
# source CoffeeScript into JavaScript.
|
||||
#
|
||||
# If included on a webpage, it will automatically sniff out, compile, and
|
||||
# execute all scripts present in `text/coffeescript` tags.
|
||||
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
{Lexer,RESERVED} = require './lexer'
|
||||
{parser} = require './parser'
|
||||
vm = require 'vm'
|
||||
|
||||
# TODO: Remove registerExtension when fully deprecated.
|
||||
if require.extensions
|
||||
require.extensions['.coffee'] = (module, filename) ->
|
||||
content = compile fs.readFileSync(filename, 'utf8'), {filename}
|
||||
module._compile content, filename
|
||||
else if require.registerExtension
|
||||
require.registerExtension '.coffee', (content) -> compile content
|
||||
|
||||
# The current CoffeeScript version number.
|
||||
exports.VERSION = '1.3.3'
|
||||
|
||||
# Words that cannot be used as identifiers in CoffeeScript code
|
||||
exports.RESERVED = RESERVED
|
||||
|
||||
# Expose helpers for testing.
|
||||
exports.helpers = require './helpers'
|
||||
|
||||
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
|
||||
# compiler.
|
||||
exports.compile = compile = (code, options = {}) ->
|
||||
{merge} = exports.helpers
|
||||
try
|
||||
js = (parser.parse lexer.tokenize code).compile options
|
||||
return js unless options.header
|
||||
catch err
|
||||
err.message = "In #{options.filename}, #{err.message}" if options.filename
|
||||
throw err
|
||||
header = "Generated by CoffeeScript #{@VERSION}"
|
||||
"// #{header}\n#{js}"
|
||||
|
||||
# Tokenize a string of CoffeeScript code, and return the array of tokens.
|
||||
exports.tokens = (code, options) ->
|
||||
lexer.tokenize code, options
|
||||
|
||||
# Parse a string of CoffeeScript code or an array of lexed tokens, and
|
||||
# return the AST. You can then compile it by calling `.compile()` on the root,
|
||||
# or traverse it by using `.traverseChildren()` with a callback.
|
||||
exports.nodes = (source, options) ->
|
||||
if typeof source is 'string'
|
||||
parser.parse lexer.tokenize source, options
|
||||
else
|
||||
parser.parse source
|
||||
|
||||
# Compile and execute a string of CoffeeScript (on the server), correctly
|
||||
# setting `__filename`, `__dirname`, and relative `require()`.
|
||||
exports.run = (code, options = {}) ->
|
||||
mainModule = require.main
|
||||
|
||||
# Set the filename.
|
||||
mainModule.filename = process.argv[1] =
|
||||
if options.filename then fs.realpathSync(options.filename) else '.'
|
||||
|
||||
# Clear the module cache.
|
||||
mainModule.moduleCache and= {}
|
||||
|
||||
# Assign paths for node_modules loading
|
||||
mainModule.paths = require('module')._nodeModulePaths path.dirname fs.realpathSync options.filename
|
||||
|
||||
# Compile.
|
||||
if path.extname(mainModule.filename) isnt '.coffee' or require.extensions
|
||||
mainModule._compile compile(code, options), mainModule.filename
|
||||
else
|
||||
mainModule._compile code, mainModule.filename
|
||||
|
||||
# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
||||
# The CoffeeScript REPL uses this to run the input.
|
||||
exports.eval = (code, options = {}) ->
|
||||
return unless code = code.trim()
|
||||
Script = vm.Script
|
||||
if Script
|
||||
if options.sandbox?
|
||||
if options.sandbox instanceof Script.createContext().constructor
|
||||
sandbox = options.sandbox
|
||||
else
|
||||
sandbox = Script.createContext()
|
||||
sandbox[k] = v for own k, v of options.sandbox
|
||||
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
|
||||
else
|
||||
sandbox = global
|
||||
sandbox.__filename = options.filename || 'eval'
|
||||
sandbox.__dirname = path.dirname sandbox.__filename
|
||||
# define module/require only if they chose not to specify their own
|
||||
unless sandbox isnt global or sandbox.module or sandbox.require
|
||||
Module = require 'module'
|
||||
sandbox.module = _module = new Module(options.modulename || 'eval')
|
||||
sandbox.require = _require = (path) -> Module._load path, _module, true
|
||||
_module.filename = sandbox.__filename
|
||||
_require[r] = require[r] for r in Object.getOwnPropertyNames require when r isnt 'paths'
|
||||
# use the same hack node currently uses for their own REPL
|
||||
_require.paths = _module.paths = Module._nodeModulePaths process.cwd()
|
||||
_require.resolve = (request) -> Module._resolveFilename request, _module
|
||||
o = {}
|
||||
o[k] = v for own k, v of options
|
||||
o.bare = on # ensure return value
|
||||
js = compile code, o
|
||||
if sandbox is global
|
||||
vm.runInThisContext js
|
||||
else
|
||||
vm.runInContext js, sandbox
|
||||
|
||||
# Instantiate a Lexer for our use here.
|
||||
lexer = new Lexer
|
||||
|
||||
# The real Lexer produces a generic stream of tokens. This object provides a
|
||||
# thin wrapper around it, compatible with the Jison API. We can then pass it
|
||||
# directly as a "Jison lexer".
|
||||
parser.lexer =
|
||||
lex: ->
|
||||
[tag, @yytext, @yylineno] = @tokens[@pos++] or ['']
|
||||
tag
|
||||
setInput: (@tokens) ->
|
||||
@pos = 0
|
||||
upcomingInput: ->
|
||||
""
|
||||
|
||||
parser.yy = require './nodes'
|
||||
0
test/fixtures/coffee/empty.coffee
vendored
0
test/fixtures/coffee/empty.coffee
vendored
1
test/fixtures/coffee/hello.coffee
vendored
1
test/fixtures/coffee/hello.coffee
vendored
@@ -1 +0,0 @@
|
||||
console.log "Hello, World!"
|
||||
28
test/fixtures/coffee/intro.coffee
vendored
28
test/fixtures/coffee/intro.coffee
vendored
@@ -1,28 +0,0 @@
|
||||
# Assignment:
|
||||
number = 42
|
||||
opposite = true
|
||||
|
||||
# Conditions:
|
||||
number = -42 if opposite
|
||||
|
||||
# Functions:
|
||||
square = (x) -> x * x
|
||||
|
||||
# Arrays:
|
||||
list = [1, 2, 3, 4, 5]
|
||||
|
||||
# Objects:
|
||||
math =
|
||||
root: Math.sqrt
|
||||
square: square
|
||||
cube: (x) -> x * square x
|
||||
|
||||
# Splats:
|
||||
race = (winner, runners...) ->
|
||||
print winner, runners
|
||||
|
||||
# Existence:
|
||||
alert "I knew it!" if elvis?
|
||||
|
||||
# Array comprehensions:
|
||||
cubes = (math.cube num for num in list)
|
||||
709
test/fixtures/coffee/lexer.coffee
vendored
709
test/fixtures/coffee/lexer.coffee
vendored
@@ -1,709 +0,0 @@
|
||||
# The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
|
||||
# matches against the beginning of the source code. When a match is found,
|
||||
# a token is produced, we consume the match, and start again. Tokens are in the
|
||||
# form:
|
||||
#
|
||||
# [tag, value, lineNumber]
|
||||
#
|
||||
# Which is a format that can be fed directly into [Jison](http://github.com/zaach/jison).
|
||||
|
||||
{Rewriter, INVERSES} = require './rewriter'
|
||||
|
||||
# Import the helpers we need.
|
||||
{count, starts, compact, last} = require './helpers'
|
||||
|
||||
# The Lexer Class
|
||||
# ---------------
|
||||
|
||||
# The Lexer class reads a stream of CoffeeScript and divvies it up into tagged
|
||||
# tokens. Some potential ambiguity in the grammar has been avoided by
|
||||
# pushing some extra smarts into the Lexer.
|
||||
exports.Lexer = class Lexer
|
||||
|
||||
# **tokenize** is the Lexer's main method. Scan by attempting to match tokens
|
||||
# one at a time, using a regular expression anchored at the start of the
|
||||
# remaining code, or a custom recursive token-matching method
|
||||
# (for interpolations). When the next token has been recorded, we move forward
|
||||
# within the code past the token, and begin again.
|
||||
#
|
||||
# Each tokenizing method is responsible for returning the number of characters
|
||||
# it has consumed.
|
||||
#
|
||||
# Before returning the token stream, run it through the [Rewriter](rewriter.html)
|
||||
# unless explicitly asked not to.
|
||||
tokenize: (code, opts = {}) ->
|
||||
code = "\n#{code}" if WHITESPACE.test code
|
||||
code = code.replace(/\r/g, '').replace TRAILING_SPACES, ''
|
||||
|
||||
@code = code # The remainder of the source code.
|
||||
@line = opts.line or 0 # The current line.
|
||||
@indent = 0 # The current indentation level.
|
||||
@indebt = 0 # The over-indentation at the current level.
|
||||
@outdebt = 0 # The under-outdentation at the current level.
|
||||
@indents = [] # The stack of all current indentation levels.
|
||||
@ends = [] # The stack for pairing up tokens.
|
||||
@tokens = [] # Stream of parsed tokens in the form `['TYPE', value, line]`.
|
||||
|
||||
# At every position, run through this list of attempted matches,
|
||||
# short-circuiting if any of them succeed. Their order determines precedence:
|
||||
# `@literalToken` is the fallback catch-all.
|
||||
i = 0
|
||||
while @chunk = code[i..]
|
||||
i += @identifierToken() or
|
||||
@commentToken() or
|
||||
@whitespaceToken() or
|
||||
@lineToken() or
|
||||
@heredocToken() or
|
||||
@stringToken() or
|
||||
@numberToken() or
|
||||
@regexToken() or
|
||||
@jsToken() or
|
||||
@literalToken()
|
||||
|
||||
@closeIndentation()
|
||||
@error "missing #{tag}" if tag = @ends.pop()
|
||||
return @tokens if opts.rewrite is off
|
||||
(new Rewriter).rewrite @tokens
|
||||
|
||||
# Tokenizers
|
||||
# ----------
|
||||
|
||||
# Matches identifying literals: variables, keywords, method names, etc.
|
||||
# Check to ensure that JavaScript reserved words aren't being used as
|
||||
# identifiers. Because CoffeeScript reserves a handful of keywords that are
|
||||
# allowed in JavaScript, we're careful not to tag them as keywords when
|
||||
# referenced as property names here, so you can still do `jQuery.is()` even
|
||||
# though `is` means `===` otherwise.
|
||||
identifierToken: ->
|
||||
return 0 unless match = IDENTIFIER.exec @chunk
|
||||
[input, id, colon] = match
|
||||
|
||||
if id is 'own' and @tag() is 'FOR'
|
||||
@token 'OWN', id
|
||||
return id.length
|
||||
forcedIdentifier = colon or
|
||||
(prev = last @tokens) and (prev[0] in ['.', '?.', '::'] or
|
||||
not prev.spaced and prev[0] is '@')
|
||||
tag = 'IDENTIFIER'
|
||||
|
||||
if not forcedIdentifier and (id in JS_KEYWORDS or id in COFFEE_KEYWORDS)
|
||||
tag = id.toUpperCase()
|
||||
if tag is 'WHEN' and @tag() in LINE_BREAK
|
||||
tag = 'LEADING_WHEN'
|
||||
else if tag is 'FOR'
|
||||
@seenFor = yes
|
||||
else if tag is 'UNLESS'
|
||||
tag = 'IF'
|
||||
else if tag in UNARY
|
||||
tag = 'UNARY'
|
||||
else if tag in RELATION
|
||||
if tag isnt 'INSTANCEOF' and @seenFor
|
||||
tag = 'FOR' + tag
|
||||
@seenFor = no
|
||||
else
|
||||
tag = 'RELATION'
|
||||
if @value() is '!'
|
||||
@tokens.pop()
|
||||
id = '!' + id
|
||||
|
||||
if id in JS_FORBIDDEN
|
||||
if forcedIdentifier
|
||||
tag = 'IDENTIFIER'
|
||||
id = new String id
|
||||
id.reserved = yes
|
||||
else if id in RESERVED
|
||||
@error "reserved word \"#{id}\""
|
||||
|
||||
unless forcedIdentifier
|
||||
id = COFFEE_ALIAS_MAP[id] if id in COFFEE_ALIASES
|
||||
tag = switch id
|
||||
when '!' then 'UNARY'
|
||||
when '==', '!=' then 'COMPARE'
|
||||
when '&&', '||' then 'LOGIC'
|
||||
when 'true', 'false' then 'BOOL'
|
||||
when 'break', 'continue' then 'STATEMENT'
|
||||
else tag
|
||||
|
||||
@token tag, id
|
||||
@token ':', ':' if colon
|
||||
input.length
|
||||
|
||||
# Matches numbers, including decimals, hex, and exponential notation.
|
||||
# Be careful not to interfere with ranges-in-progress.
|
||||
numberToken: ->
|
||||
return 0 unless match = NUMBER.exec @chunk
|
||||
number = match[0]
|
||||
if /^0[BOX]/.test number
|
||||
@error "radix prefix '#{number}' must be lowercase"
|
||||
else if /E/.test(number) and not /^0x/.test number
|
||||
@error "exponential notation '#{number}' must be indicated with a lowercase 'e'"
|
||||
else if /^0\d*[89]/.test number
|
||||
@error "decimal literal '#{number}' must not be prefixed with '0'"
|
||||
else if /^0\d+/.test number
|
||||
@error "octal literal '#{number}' must be prefixed with '0o'"
|
||||
lexedLength = number.length
|
||||
if octalLiteral = /^0o([0-7]+)/.exec number
|
||||
number = '0x' + (parseInt octalLiteral[1], 8).toString 16
|
||||
if binaryLiteral = /^0b([01]+)/.exec number
|
||||
number = '0x' + (parseInt binaryLiteral[1], 2).toString 16
|
||||
@token 'NUMBER', number
|
||||
lexedLength
|
||||
|
||||
# Matches strings, including multi-line strings. Ensures that quotation marks
|
||||
# are balanced within the string's contents, and within nested interpolations.
|
||||
stringToken: ->
|
||||
switch @chunk.charAt 0
|
||||
when "'"
|
||||
return 0 unless match = SIMPLESTR.exec @chunk
|
||||
@token 'STRING', (string = match[0]).replace MULTILINER, '\\\n'
|
||||
when '"'
|
||||
return 0 unless string = @balancedString @chunk, '"'
|
||||
if 0 < string.indexOf '#{', 1
|
||||
@interpolateString string[1...-1]
|
||||
else
|
||||
@token 'STRING', @escapeLines string
|
||||
else
|
||||
return 0
|
||||
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
|
||||
@error "octal escape sequences #{string} are not allowed"
|
||||
@line += count string, '\n'
|
||||
string.length
|
||||
|
||||
# Matches heredocs, adjusting indentation to the correct level, as heredocs
|
||||
# preserve whitespace, but ignore indentation to the left.
|
||||
heredocToken: ->
|
||||
return 0 unless match = HEREDOC.exec @chunk
|
||||
heredoc = match[0]
|
||||
quote = heredoc.charAt 0
|
||||
doc = @sanitizeHeredoc match[2], quote: quote, indent: null
|
||||
if quote is '"' and 0 <= doc.indexOf '#{'
|
||||
@interpolateString doc, heredoc: yes
|
||||
else
|
||||
@token 'STRING', @makeString doc, quote, yes
|
||||
@line += count heredoc, '\n'
|
||||
heredoc.length
|
||||
|
||||
# Matches and consumes comments.
|
||||
commentToken: ->
|
||||
return 0 unless match = @chunk.match COMMENT
|
||||
[comment, here] = match
|
||||
if here
|
||||
@token 'HERECOMMENT', @sanitizeHeredoc here,
|
||||
herecomment: true, indent: Array(@indent + 1).join(' ')
|
||||
@line += count comment, '\n'
|
||||
comment.length
|
||||
|
||||
# Matches JavaScript interpolated directly into the source via backticks.
|
||||
jsToken: ->
|
||||
return 0 unless @chunk.charAt(0) is '`' and match = JSTOKEN.exec @chunk
|
||||
@token 'JS', (script = match[0])[1...-1]
|
||||
script.length
|
||||
|
||||
# Matches regular expression literals. Lexing regular expressions is difficult
|
||||
# to distinguish from division, so we borrow some basic heuristics from
|
||||
# JavaScript and Ruby.
|
||||
regexToken: ->
|
||||
return 0 if @chunk.charAt(0) isnt '/'
|
||||
if match = HEREGEX.exec @chunk
|
||||
length = @heregexToken match
|
||||
@line += count match[0], '\n'
|
||||
return length
|
||||
|
||||
prev = last @tokens
|
||||
return 0 if prev and (prev[0] in (if prev.spaced then NOT_REGEX else NOT_SPACED_REGEX))
|
||||
return 0 unless match = REGEX.exec @chunk
|
||||
[match, regex, flags] = match
|
||||
if regex[..1] is '/*' then @error 'regular expressions cannot begin with `*`'
|
||||
if regex is '//' then regex = '/(?:)/'
|
||||
@token 'REGEX', "#{regex}#{flags}"
|
||||
match.length
|
||||
|
||||
# Matches multiline extended regular expressions.
|
||||
heregexToken: (match) ->
|
||||
[heregex, body, flags] = match
|
||||
if 0 > body.indexOf '#{'
|
||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
|
||||
if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
|
||||
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
|
||||
return heregex.length
|
||||
@token 'IDENTIFIER', 'RegExp'
|
||||
@tokens.push ['CALL_START', '(']
|
||||
tokens = []
|
||||
for [tag, value] in @interpolateString(body, regex: yes)
|
||||
if tag is 'TOKENS'
|
||||
tokens.push value...
|
||||
else
|
||||
continue unless value = value.replace HEREGEX_OMIT, ''
|
||||
value = value.replace /\\/g, '\\\\'
|
||||
tokens.push ['STRING', @makeString(value, '"', yes)]
|
||||
tokens.push ['+', '+']
|
||||
tokens.pop()
|
||||
@tokens.push ['STRING', '""'], ['+', '+'] unless tokens[0]?[0] is 'STRING'
|
||||
@tokens.push tokens...
|
||||
@tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags
|
||||
@token ')', ')'
|
||||
heregex.length
|
||||
|
||||
# Matches newlines, indents, and outdents, and determines which is which.
|
||||
# If we can detect that the current line is continued onto the the next line,
|
||||
# then the newline is suppressed:
|
||||
#
|
||||
# elements
|
||||
# .each( ... )
|
||||
# .map( ... )
|
||||
#
|
||||
# Keeps track of the level of indentation, because a single outdent token
|
||||
# can close multiple indents, so we need to know how far in we happen to be.
|
||||
lineToken: ->
|
||||
return 0 unless match = MULTI_DENT.exec @chunk
|
||||
indent = match[0]
|
||||
@line += count indent, '\n'
|
||||
@seenFor = no
|
||||
size = indent.length - 1 - indent.lastIndexOf '\n'
|
||||
noNewlines = @unfinished()
|
||||
if size - @indebt is @indent
|
||||
if noNewlines then @suppressNewlines() else @newlineToken()
|
||||
return indent.length
|
||||
if size > @indent
|
||||
if noNewlines
|
||||
@indebt = size - @indent
|
||||
@suppressNewlines()
|
||||
return indent.length
|
||||
diff = size - @indent + @outdebt
|
||||
@token 'INDENT', diff
|
||||
@indents.push diff
|
||||
@ends.push 'OUTDENT'
|
||||
@outdebt = @indebt = 0
|
||||
else
|
||||
@indebt = 0
|
||||
@outdentToken @indent - size, noNewlines
|
||||
@indent = size
|
||||
indent.length
|
||||
|
||||
# Record an outdent token or multiple tokens, if we happen to be moving back
|
||||
# inwards past several recorded indents.
|
||||
outdentToken: (moveOut, noNewlines) ->
|
||||
while moveOut > 0
|
||||
len = @indents.length - 1
|
||||
if @indents[len] is undefined
|
||||
moveOut = 0
|
||||
else if @indents[len] is @outdebt
|
||||
moveOut -= @outdebt
|
||||
@outdebt = 0
|
||||
else if @indents[len] < @outdebt
|
||||
@outdebt -= @indents[len]
|
||||
moveOut -= @indents[len]
|
||||
else
|
||||
dent = @indents.pop() - @outdebt
|
||||
moveOut -= dent
|
||||
@outdebt = 0
|
||||
@pair 'OUTDENT'
|
||||
@token 'OUTDENT', dent
|
||||
@outdebt -= moveOut if dent
|
||||
@tokens.pop() while @value() is ';'
|
||||
@token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR' or noNewlines
|
||||
this
|
||||
|
||||
# Matches and consumes non-meaningful whitespace. Tag the previous token
|
||||
# as being "spaced", because there are some cases where it makes a difference.
|
||||
whitespaceToken: ->
|
||||
return 0 unless (match = WHITESPACE.exec @chunk) or
|
||||
(nline = @chunk.charAt(0) is '\n')
|
||||
prev = last @tokens
|
||||
prev[if match then 'spaced' else 'newLine'] = true if prev
|
||||
if match then match[0].length else 0
|
||||
|
||||
# Generate a newline token. Consecutive newlines get merged together.
|
||||
newlineToken: ->
|
||||
@tokens.pop() while @value() is ';'
|
||||
@token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR'
|
||||
this
|
||||
|
||||
# Use a `\` at a line-ending to suppress the newline.
|
||||
# The slash is removed here once its job is done.
|
||||
suppressNewlines: ->
|
||||
@tokens.pop() if @value() is '\\'
|
||||
this
|
||||
|
||||
# We treat all other single characters as a token. E.g.: `( ) , . !`
|
||||
# Multi-character operators are also literal tokens, so that Jison can assign
|
||||
# the proper order of operations. There are some symbols that we tag specially
|
||||
# here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish
|
||||
# parentheses that indicate a method call from regular parentheses, and so on.
|
||||
literalToken: ->
|
||||
if match = OPERATOR.exec @chunk
|
||||
[value] = match
|
||||
@tagParameters() if CODE.test value
|
||||
else
|
||||
value = @chunk.charAt 0
|
||||
tag = value
|
||||
prev = last @tokens
|
||||
if value is '=' and prev
|
||||
if not prev[1].reserved and prev[1] in JS_FORBIDDEN
|
||||
@error "reserved word \"#{@value()}\" can't be assigned"
|
||||
if prev[1] in ['||', '&&']
|
||||
prev[0] = 'COMPOUND_ASSIGN'
|
||||
prev[1] += '='
|
||||
return value.length
|
||||
if value is ';'
|
||||
@seenFor = no
|
||||
tag = 'TERMINATOR'
|
||||
else if value in MATH then tag = 'MATH'
|
||||
else if value in COMPARE then tag = 'COMPARE'
|
||||
else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
|
||||
else if value in UNARY then tag = 'UNARY'
|
||||
else if value in SHIFT then tag = 'SHIFT'
|
||||
else if value in LOGIC or value is '?' and prev?.spaced then tag = 'LOGIC'
|
||||
else if prev and not prev.spaced
|
||||
if value is '(' and prev[0] in CALLABLE
|
||||
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
|
||||
tag = 'CALL_START'
|
||||
else if value is '[' and prev[0] in INDEXABLE
|
||||
tag = 'INDEX_START'
|
||||
switch prev[0]
|
||||
when '?' then prev[0] = 'INDEX_SOAK'
|
||||
switch value
|
||||
when '(', '{', '[' then @ends.push INVERSES[value]
|
||||
when ')', '}', ']' then @pair value
|
||||
@token tag, value
|
||||
value.length
|
||||
|
||||
# Token Manipulators
|
||||
# ------------------
|
||||
|
||||
# Sanitize a heredoc or herecomment by
|
||||
# erasing all external indentation on the left-hand side.
|
||||
sanitizeHeredoc: (doc, options) ->
|
||||
{indent, herecomment} = options
|
||||
if herecomment
|
||||
if HEREDOC_ILLEGAL.test doc
|
||||
@error "block comment cannot contain \"*/\", starting"
|
||||
return doc if doc.indexOf('\n') <= 0
|
||||
else
|
||||
while match = HEREDOC_INDENT.exec doc
|
||||
attempt = match[1]
|
||||
indent = attempt if indent is null or 0 < attempt.length < indent.length
|
||||
doc = doc.replace /// \n #{indent} ///g, '\n' if indent
|
||||
doc = doc.replace /^\n/, '' unless herecomment
|
||||
doc
|
||||
|
||||
# A source of ambiguity in our grammar used to be parameter lists in function
|
||||
# definitions versus argument lists in function calls. Walk backwards, tagging
|
||||
# parameters specially in order to make things easier for the parser.
|
||||
tagParameters: ->
|
||||
return this if @tag() isnt ')'
|
||||
stack = []
|
||||
{tokens} = this
|
||||
i = tokens.length
|
||||
tokens[--i][0] = 'PARAM_END'
|
||||
while tok = tokens[--i]
|
||||
switch tok[0]
|
||||
when ')'
|
||||
stack.push tok
|
||||
when '(', 'CALL_START'
|
||||
if stack.length then stack.pop()
|
||||
else if tok[0] is '('
|
||||
tok[0] = 'PARAM_START'
|
||||
return this
|
||||
else return this
|
||||
this
|
||||
|
||||
# Close up all remaining open blocks at the end of the file.
|
||||
closeIndentation: ->
|
||||
@outdentToken @indent
|
||||
|
||||
# Matches a balanced group such as a single or double-quoted string. Pass in
|
||||
# a series of delimiters, all of which must be nested correctly within the
|
||||
# contents of the string. This method allows us to have strings within
|
||||
# interpolations within strings, ad infinitum.
|
||||
balancedString: (str, end) ->
|
||||
continueCount = 0
|
||||
stack = [end]
|
||||
for i in [1...str.length]
|
||||
if continueCount
|
||||
--continueCount
|
||||
continue
|
||||
switch letter = str.charAt i
|
||||
when '\\'
|
||||
++continueCount
|
||||
continue
|
||||
when end
|
||||
stack.pop()
|
||||
unless stack.length
|
||||
return str[0..i]
|
||||
end = stack[stack.length - 1]
|
||||
continue
|
||||
if end is '}' and letter in ['"', "'"]
|
||||
stack.push end = letter
|
||||
else if end is '}' and letter is '/' and match = (HEREGEX.exec(str[i..]) or REGEX.exec(str[i..]))
|
||||
continueCount += match[0].length - 1
|
||||
else if end is '}' and letter is '{'
|
||||
stack.push end = '}'
|
||||
else if end is '"' and prev is '#' and letter is '{'
|
||||
stack.push end = '}'
|
||||
prev = letter
|
||||
@error "missing #{ stack.pop() }, starting"
|
||||
|
||||
# Expand variables and expressions inside double-quoted strings using
|
||||
# Ruby-like notation for substitution of arbitrary expressions.
|
||||
#
|
||||
# "Hello #{name.capitalize()}."
|
||||
#
|
||||
# If it encounters an interpolation, this method will recursively create a
|
||||
# new Lexer, tokenize the interpolated contents, and merge them into the
|
||||
# token stream.
|
||||
interpolateString: (str, options = {}) ->
|
||||
{heredoc, regex} = options
|
||||
tokens = []
|
||||
pi = 0
|
||||
i = -1
|
||||
while letter = str.charAt i += 1
|
||||
if letter is '\\'
|
||||
i += 1
|
||||
continue
|
||||
unless letter is '#' and str.charAt(i+1) is '{' and
|
||||
(expr = @balancedString str[i + 1..], '}')
|
||||
continue
|
||||
tokens.push ['NEOSTRING', str[pi...i]] if pi < i
|
||||
inner = expr[1...-1]
|
||||
if inner.length
|
||||
nested = new Lexer().tokenize inner, line: @line, rewrite: off
|
||||
nested.pop()
|
||||
nested.shift() if nested[0]?[0] is 'TERMINATOR'
|
||||
if len = nested.length
|
||||
if len > 1
|
||||
nested.unshift ['(', '(', @line]
|
||||
nested.push [')', ')', @line]
|
||||
tokens.push ['TOKENS', nested]
|
||||
i += expr.length
|
||||
pi = i + 1
|
||||
tokens.push ['NEOSTRING', str[pi..]] if i > pi < str.length
|
||||
return tokens if regex
|
||||
return @token 'STRING', '""' unless tokens.length
|
||||
tokens.unshift ['', ''] unless tokens[0][0] is 'NEOSTRING'
|
||||
@token '(', '(' if interpolated = tokens.length > 1
|
||||
for [tag, value], i in tokens
|
||||
@token '+', '+' if i
|
||||
if tag is 'TOKENS'
|
||||
@tokens.push value...
|
||||
else
|
||||
@token 'STRING', @makeString value, '"', heredoc
|
||||
@token ')', ')' if interpolated
|
||||
tokens
|
||||
|
||||
# Pairs up a closing token, ensuring that all listed pairs of tokens are
|
||||
# correctly balanced throughout the course of the token stream.
|
||||
pair: (tag) ->
|
||||
unless tag is wanted = last @ends
|
||||
@error "unmatched #{tag}" unless 'OUTDENT' is wanted
|
||||
# Auto-close INDENT to support syntax like this:
|
||||
#
|
||||
# el.click((event) ->
|
||||
# el.hide())
|
||||
#
|
||||
@indent -= size = last @indents
|
||||
@outdentToken size, true
|
||||
return @pair tag
|
||||
@ends.pop()
|
||||
|
||||
# Helpers
|
||||
# -------
|
||||
|
||||
# Add a token to the results, taking note of the line number.
|
||||
token: (tag, value) ->
|
||||
@tokens.push [tag, value, @line]
|
||||
|
||||
# Peek at a tag in the current token stream.
|
||||
tag: (index, tag) ->
|
||||
(tok = last @tokens, index) and if tag then tok[0] = tag else tok[0]
|
||||
|
||||
# Peek at a value in the current token stream.
|
||||
value: (index, val) ->
|
||||
(tok = last @tokens, index) and if val then tok[1] = val else tok[1]
|
||||
|
||||
# Are we in the midst of an unfinished expression?
|
||||
unfinished: ->
|
||||
LINE_CONTINUER.test(@chunk) or
|
||||
@tag() in ['\\', '.', '?.', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION'
|
||||
'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||
|
||||
# Converts newlines for string literals.
|
||||
escapeLines: (str, heredoc) ->
|
||||
str.replace MULTILINER, if heredoc then '\\n' else ''
|
||||
|
||||
# Constructs a string token by escaping quotes and newlines.
|
||||
makeString: (body, quote, heredoc) ->
|
||||
return quote + quote unless body
|
||||
body = body.replace /\\([\s\S])/g, (match, contents) ->
|
||||
if contents in ['\n', quote] then contents else match
|
||||
body = body.replace /// #{quote} ///g, '\\$&'
|
||||
quote + @escapeLines(body, heredoc) + quote
|
||||
|
||||
# Throws a syntax error on the current `@line`.
|
||||
error: (message) ->
|
||||
throw SyntaxError "#{message} on line #{ @line + 1}"
|
||||
|
||||
# Constants
|
||||
# ---------
|
||||
|
||||
# Keywords that CoffeeScript shares in common with JavaScript.
|
||||
JS_KEYWORDS = [
|
||||
'true', 'false', 'null', 'this'
|
||||
'new', 'delete', 'typeof', 'in', 'instanceof'
|
||||
'return', 'throw', 'break', 'continue', 'debugger'
|
||||
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
|
||||
'class', 'extends', 'super'
|
||||
]
|
||||
|
||||
# CoffeeScript-only keywords.
|
||||
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']
|
||||
|
||||
COFFEE_ALIAS_MAP =
|
||||
and : '&&'
|
||||
or : '||'
|
||||
is : '=='
|
||||
isnt : '!='
|
||||
not : '!'
|
||||
yes : 'true'
|
||||
no : 'false'
|
||||
on : 'true'
|
||||
off : 'false'
|
||||
|
||||
COFFEE_ALIASES = (key for key of COFFEE_ALIAS_MAP)
|
||||
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
|
||||
|
||||
# The list of keywords that are reserved by JavaScript, but not used, or are
|
||||
# used by CoffeeScript internally. We throw an error when these are encountered,
|
||||
# to avoid having a JavaScript error at runtime.
|
||||
RESERVED = [
|
||||
'case', 'default', 'function', 'var', 'void', 'with'
|
||||
'const', 'let', 'enum', 'export', 'import', 'native'
|
||||
'__hasProp', '__extends', '__slice', '__bind', '__indexOf'
|
||||
'implements', 'interface', 'let', 'package',
|
||||
'private', 'protected', 'public', 'static', 'yield'
|
||||
]
|
||||
|
||||
STRICT_PROSCRIBED = ['arguments', 'eval']
|
||||
|
||||
# The superset of both JavaScript keywords and reserved words, none of which may
|
||||
# be used as identifiers or properties.
|
||||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED)
|
||||
|
||||
exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED)
|
||||
exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED
|
||||
|
||||
# Token matching regexes.
|
||||
IDENTIFIER = /// ^
|
||||
( [$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]* )
|
||||
( [^\n\S]* : (?!:) )? # Is this a property name?
|
||||
///
|
||||
|
||||
NUMBER = ///
|
||||
^ 0b[01]+ | # binary
|
||||
^ 0o[0-7]+ | # octal
|
||||
^ 0x[\da-f]+ | # hex
|
||||
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
|
||||
///i
|
||||
|
||||
HEREDOC = /// ^ ("""|''') ([\s\S]*?) (?:\n[^\n\S]*)? \1 ///
|
||||
|
||||
OPERATOR = /// ^ (
|
||||
?: [-=]> # function
|
||||
| [-+*/%<>&|^!?=]= # compound assign / compare
|
||||
| >>>=? # zero-fill right shift
|
||||
| ([-+:])\1 # doubles
|
||||
| ([&|<>])\2=? # logic / shift
|
||||
| \?\. # soak access
|
||||
| \.{2,3} # range or splat
|
||||
) ///
|
||||
|
||||
WHITESPACE = /^[^\n\S]+/
|
||||
|
||||
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/
|
||||
|
||||
CODE = /^[-=]>/
|
||||
|
||||
MULTI_DENT = /^(?:\n[^\n\S]*)+/
|
||||
|
||||
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/
|
||||
|
||||
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
|
||||
|
||||
# Regex-matching-regexes.
|
||||
REGEX = /// ^
|
||||
(/ (?! [\s=] ) # disallow leading whitespace or equals signs
|
||||
[^ [ / \n \\ ]* # every other thing
|
||||
(?:
|
||||
(?: \\[\s\S] # anything escaped
|
||||
| \[ # character class
|
||||
[^ \] \n \\ ]*
|
||||
(?: \\[\s\S] [^ \] \n \\ ]* )*
|
||||
]
|
||||
) [^ [ / \n \\ ]*
|
||||
)*
|
||||
/) ([imgy]{0,4}) (?!\w)
|
||||
///
|
||||
|
||||
HEREGEX = /// ^ /{3} ([\s\S]+?) /{3} ([imgy]{0,4}) (?!\w) ///
|
||||
|
||||
HEREGEX_OMIT = /\s+(?:#.*)?/g
|
||||
|
||||
# Token cleaning regexes.
|
||||
MULTILINER = /\n/g
|
||||
|
||||
HEREDOC_INDENT = /\n+([^\n\S]*)/g
|
||||
|
||||
HEREDOC_ILLEGAL = /\*\//
|
||||
|
||||
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | :: ) ///
|
||||
|
||||
TRAILING_SPACES = /\s+$/
|
||||
|
||||
# Compound assignment tokens.
|
||||
COMPOUND_ASSIGN = [
|
||||
'-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='
|
||||
]
|
||||
|
||||
# Unary tokens.
|
||||
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']
|
||||
|
||||
# Logical tokens.
|
||||
LOGIC = ['&&', '||', '&', '|', '^']
|
||||
|
||||
# Bit-shifting tokens.
|
||||
SHIFT = ['<<', '>>', '>>>']
|
||||
|
||||
# Comparison tokens.
|
||||
COMPARE = ['==', '!=', '<', '>', '<=', '>=']
|
||||
|
||||
# Mathematical tokens.
|
||||
MATH = ['*', '/', '%']
|
||||
|
||||
# Relational tokens that are negatable with `not` prefix.
|
||||
RELATION = ['IN', 'OF', 'INSTANCEOF']
|
||||
|
||||
# Boolean tokens.
|
||||
BOOL = ['TRUE', 'FALSE']
|
||||
|
||||
# Tokens which a regular expression will never immediately follow, but which
|
||||
# a division operator might.
|
||||
#
|
||||
# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
|
||||
#
|
||||
# Our list is shorter, due to sans-parentheses method calls.
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--', ']']
|
||||
|
||||
# If the previous token is not spaced, there are more preceding tokens that
|
||||
# force a division parse:
|
||||
NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING'
|
||||
|
||||
# Tokens which could legitimately be invoked or indexed. An opening
|
||||
# parentheses or bracket following these tokens will be recorded as the start
|
||||
# of a function invocation or indexing operation.
|
||||
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']
|
||||
INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL', 'NULL', 'UNDEFINED'
|
||||
|
||||
# Tokens that, when immediately preceding a `WHEN`, indicate that the `WHEN`
|
||||
# occurs at the start of a line. We disambiguate these from trailing whens to
|
||||
# avoid an ambiguity in the grammar.
|
||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
|
||||
256
test/fixtures/coffee/rack_application.coffee
vendored
256
test/fixtures/coffee/rack_application.coffee
vendored
@@ -1,256 +0,0 @@
|
||||
# The `RackApplication` class is responsible for managing a
|
||||
# [Nack](http://josh.github.com/nack/) pool for a given Rack
|
||||
# application. Incoming HTTP requests are dispatched to
|
||||
# `RackApplication` instances by an `HttpServer`, where they are
|
||||
# subsequently handled by a pool of Nack worker processes. By default,
|
||||
# Pow tells Nack to use a maximum of two worker processes per
|
||||
# application, but this can be overridden with the configuration's
|
||||
# `workers` option.
|
||||
#
|
||||
# Before creating the Nack pool, Pow executes the `.powrc` and
|
||||
# `.powenv` scripts if they're present in the application root,
|
||||
# captures their environment variables, and passes them along to the
|
||||
# Nack worker processes. This lets you modify your `RUBYOPT` to use
|
||||
# different Ruby options, for example.
|
||||
#
|
||||
# If [rvm](http://rvm.beginrescueend.com/) is installed and an
|
||||
# `.rvmrc` file is present in the application's root, Pow will load
|
||||
# both before creating the Nack pool. This makes it easy to run an
|
||||
# app with a specific version of Ruby.
|
||||
#
|
||||
# Nack workers remain running until they're killed, restarted (by
|
||||
# touching the `tmp/restart.txt` file in the application root), or
|
||||
# until the application has not served requests for the length of time
|
||||
# specified in the configuration's `timeout` option (15 minutes by
|
||||
# default).
|
||||
|
||||
async = require "async"
|
||||
fs = require "fs"
|
||||
nack = require "nack"
|
||||
|
||||
{bufferLines, pause, sourceScriptEnv} = require "./util"
|
||||
{join, exists, basename, resolve} = require "path"
|
||||
|
||||
module.exports = class RackApplication
|
||||
# Create a `RackApplication` for the given configuration and
|
||||
# root path. The application begins life in the uninitialized
|
||||
# state.
|
||||
constructor: (@configuration, @root, @firstHost) ->
|
||||
@logger = @configuration.getLogger join "apps", basename @root
|
||||
@readyCallbacks = []
|
||||
@quitCallbacks = []
|
||||
@statCallbacks = []
|
||||
|
||||
# Queue `callback` to be invoked when the application becomes ready,
|
||||
# then start the initialization process. If the application's state
|
||||
# is ready, the callback is invoked immediately.
|
||||
ready: (callback) ->
|
||||
if @state is "ready"
|
||||
callback()
|
||||
else
|
||||
@readyCallbacks.push callback
|
||||
@initialize()
|
||||
|
||||
# Tell the application to quit and queue `callback` to be invoked
|
||||
# when all workers have exited. If the application has already quit,
|
||||
# the callback is invoked immediately.
|
||||
quit: (callback) ->
|
||||
if @state
|
||||
@quitCallbacks.push callback if callback
|
||||
@terminate()
|
||||
else
|
||||
callback?()
|
||||
|
||||
# Stat `tmp/restart.txt` in the application root and invoke the
|
||||
# given callback with a single argument indicating whether or not
|
||||
# the file has been touched since the last call to
|
||||
# `queryRestartFile`.
|
||||
queryRestartFile: (callback) ->
|
||||
fs.stat join(@root, "tmp/restart.txt"), (err, stats) =>
|
||||
if err
|
||||
@mtime = null
|
||||
callback false
|
||||
else
|
||||
lastMtime = @mtime
|
||||
@mtime = stats.mtime.getTime()
|
||||
callback lastMtime isnt @mtime
|
||||
|
||||
# Check to see if `tmp/always_restart.txt` is present in the
|
||||
# application root, and set the pool's `runOnce` option
|
||||
# accordingly. Invoke `callback` when the existence check has
|
||||
# finished. (Multiple calls to this method are aggregated.)
|
||||
setPoolRunOnceFlag: (callback) ->
|
||||
unless @statCallbacks.length
|
||||
exists join(@root, "tmp/always_restart.txt"), (alwaysRestart) =>
|
||||
@pool.runOnce = alwaysRestart
|
||||
statCallback() for statCallback in @statCallbacks
|
||||
@statCallbacks = []
|
||||
|
||||
@statCallbacks.push callback
|
||||
|
||||
# Collect environment variables from `.powrc` and `.powenv`, in that
|
||||
# order, if present. The idea is that `.powrc` files can be checked
|
||||
# into a source code repository for global configuration, leaving
|
||||
# `.powenv` free for any necessary local overrides.
|
||||
loadScriptEnvironment: (env, callback) ->
|
||||
async.reduce [".powrc", ".envrc", ".powenv"], env, (env, filename, callback) =>
|
||||
exists script = join(@root, filename), (scriptExists) ->
|
||||
if scriptExists
|
||||
sourceScriptEnv script, env, callback
|
||||
else
|
||||
callback null, env
|
||||
, callback
|
||||
|
||||
# If `.rvmrc` and `$HOME/.rvm/scripts/rvm` are present, load rvm,
|
||||
# source `.rvmrc`, and invoke `callback` with the resulting
|
||||
# environment variables. If `.rvmrc` is present but rvm is not
|
||||
# installed, invoke `callback` without sourcing `.rvmrc`.
|
||||
# Before loading rvm, Pow invokes a helper script that shows a
|
||||
# deprecation notice if it has not yet been displayed.
|
||||
loadRvmEnvironment: (env, callback) ->
|
||||
exists script = join(@root, ".rvmrc"), (rvmrcExists) =>
|
||||
if rvmrcExists
|
||||
exists rvm = @configuration.rvmPath, (rvmExists) =>
|
||||
if rvmExists
|
||||
libexecPath = resolve "#{__dirname}/../libexec"
|
||||
before = """
|
||||
'#{libexecPath}/pow_rvm_deprecation_notice' '#{[@firstHost]}'
|
||||
source '#{rvm}' > /dev/null
|
||||
""".trim()
|
||||
sourceScriptEnv script, env, {before}, callback
|
||||
else
|
||||
callback null, env
|
||||
else
|
||||
callback null, env
|
||||
|
||||
# Stat `tmp/restart.txt` to cache its mtime, then load the
|
||||
# application's full environment from `.powrc`, `.powenv`, and
|
||||
# `.rvmrc`.
|
||||
loadEnvironment: (callback) ->
|
||||
@queryRestartFile =>
|
||||
@loadScriptEnvironment @configuration.env, (err, env) =>
|
||||
if err then callback err
|
||||
else @loadRvmEnvironment env, (err, env) =>
|
||||
if err then callback err
|
||||
else callback null, env
|
||||
|
||||
# Begin the initialization process if the application is in the
|
||||
# uninitialized state. (If the application is terminating, queue a
|
||||
# call to `initialize` after all workers have exited.)
|
||||
initialize: ->
|
||||
if @state
|
||||
if @state is "terminating"
|
||||
@quit => @initialize()
|
||||
return
|
||||
|
||||
@state = "initializing"
|
||||
|
||||
# Load the application's environment. If an error is raised or
|
||||
# either of the environment scripts exits with a non-zero status,
|
||||
# reset the application's state and log the error.
|
||||
@loadEnvironment (err, env) =>
|
||||
if err
|
||||
@state = null
|
||||
@logger.error err.message
|
||||
@logger.error "stdout: #{err.stdout}"
|
||||
@logger.error "stderr: #{err.stderr}"
|
||||
|
||||
# Set the application's state to ready. Then create the Nack
|
||||
# pool instance using the `workers` and `timeout` options from
|
||||
# the application's environment or the global configuration.
|
||||
else
|
||||
@state = "ready"
|
||||
|
||||
@pool = nack.createPool join(@root, "config.ru"),
|
||||
env: env
|
||||
size: env?.POW_WORKERS ? @configuration.workers
|
||||
idle: (env?.POW_TIMEOUT ? @configuration.timeout) * 1000
|
||||
|
||||
# Log the workers' stderr and stdout, and log each worker's
|
||||
# PID as it spawns and exits.
|
||||
bufferLines @pool.stdout, (line) => @logger.info line
|
||||
bufferLines @pool.stderr, (line) => @logger.warning line
|
||||
|
||||
@pool.on "worker:spawn", (process) =>
|
||||
@logger.debug "nack worker #{process.child.pid} spawned"
|
||||
|
||||
@pool.on "worker:exit", (process) =>
|
||||
@logger.debug "nack worker exited"
|
||||
|
||||
# Invoke and remove all queued callbacks, passing along the
|
||||
# error, if any.
|
||||
readyCallback err for readyCallback in @readyCallbacks
|
||||
@readyCallbacks = []
|
||||
|
||||
# Begin the termination process. (If the application is initializing,
|
||||
# wait until it is ready before shutting down.)
|
||||
terminate: ->
|
||||
if @state is "initializing"
|
||||
@ready => @terminate()
|
||||
|
||||
else if @state is "ready"
|
||||
@state = "terminating"
|
||||
|
||||
# Instruct all workers to exit. After the processes have
|
||||
# terminated, reset the application's state, then invoke and
|
||||
# remove all queued callbacks.
|
||||
@pool.quit =>
|
||||
@state = null
|
||||
@mtime = null
|
||||
@pool = null
|
||||
|
||||
quitCallback() for quitCallback in @quitCallbacks
|
||||
@quitCallbacks = []
|
||||
|
||||
# Handle an incoming HTTP request. Wait until the application is in
|
||||
# the ready state, restart the workers if necessary, then pass the
|
||||
# request along to the Nack pool. If the Nack worker raises an
|
||||
# exception handling the request, reset the application.
|
||||
handle: (req, res, next, callback) ->
|
||||
resume = pause req
|
||||
@ready (err) =>
|
||||
return next err if err
|
||||
@setPoolRunOnceFlag =>
|
||||
@restartIfNecessary =>
|
||||
req.proxyMetaVariables =
|
||||
SERVER_PORT: @configuration.dstPort.toString()
|
||||
try
|
||||
@pool.proxy req, res, (err) =>
|
||||
@quit() if err
|
||||
next err
|
||||
finally
|
||||
resume()
|
||||
callback?()
|
||||
|
||||
# Terminate the application, re-initialize it, and invoke the given
|
||||
# callback when the application's state becomes ready.
|
||||
restart: (callback) ->
|
||||
@quit =>
|
||||
@ready callback
|
||||
|
||||
# Restart the application if `tmp/restart.txt` has been touched
|
||||
# since the last call to this function.
|
||||
restartIfNecessary: (callback) ->
|
||||
@queryRestartFile (mtimeChanged) =>
|
||||
if mtimeChanged
|
||||
@restart callback
|
||||
else
|
||||
callback()
|
||||
|
||||
# Append RVM autoload boilerplate to the application's `.powrc`
|
||||
# file. This is called by the RVM deprecation notice mini-app.
|
||||
writeRvmBoilerplate: ->
|
||||
powrc = join @root, ".powrc"
|
||||
boilerplate = @constructor.rvmBoilerplate
|
||||
|
||||
fs.readFile powrc, "utf8", (err, contents) ->
|
||||
contents ?= ""
|
||||
if contents.indexOf(boilerplate) is -1
|
||||
fs.writeFile powrc, "#{boilerplate}\n#{contents}"
|
||||
|
||||
@rvmBoilerplate: """
|
||||
if [ -f "$rvm_path/scripts/rvm" ] && [ -f ".rvmrc" ]; then
|
||||
source "$rvm_path/scripts/rvm"
|
||||
source ".rvmrc"
|
||||
fi
|
||||
"""
|
||||
110
test/fixtures/coffee/xipd.coffee
vendored
110
test/fixtures/coffee/xipd.coffee
vendored
@@ -1,110 +0,0 @@
|
||||
dnsserver = require "dnsserver"
|
||||
|
||||
exports.Server = class Server extends dnsserver.Server
|
||||
NS_T_A = 1
|
||||
NS_T_NS = 2
|
||||
NS_T_CNAME = 5
|
||||
NS_T_SOA = 6
|
||||
NS_C_IN = 1
|
||||
NS_RCODE_NXDOMAIN = 3
|
||||
|
||||
constructor: (domain, @rootAddress) ->
|
||||
super
|
||||
@domain = domain.toLowerCase()
|
||||
@soa = createSOA @domain
|
||||
@on "request", @handleRequest
|
||||
|
||||
handleRequest: (req, res) =>
|
||||
question = req.question
|
||||
subdomain = @extractSubdomain question.name
|
||||
|
||||
if subdomain? and isARequest question
|
||||
res.addRR question.name, NS_T_A, NS_C_IN, 600, subdomain.getAddress()
|
||||
else if subdomain?.isEmpty() and isNSRequest question
|
||||
res.addRR question.name, NS_T_SOA, NS_C_IN, 600, @soa, true
|
||||
else
|
||||
res.header.rcode = NS_RCODE_NXDOMAIN
|
||||
|
||||
res.send()
|
||||
|
||||
extractSubdomain: (name) ->
|
||||
Subdomain.extract name, @domain, @rootAddress
|
||||
|
||||
isARequest = (question) ->
|
||||
question.type is NS_T_A and question.class is NS_C_IN
|
||||
|
||||
isNSRequest = (question) ->
|
||||
question.type is NS_T_NS and question.class is NS_C_IN
|
||||
|
||||
createSOA = (domain) ->
|
||||
mname = "ns-1.#{domain}"
|
||||
rname = "hostmaster.#{domain}"
|
||||
serial = parseInt new Date().getTime() / 1000
|
||||
refresh = 28800
|
||||
retry = 7200
|
||||
expire = 604800
|
||||
minimum = 3600
|
||||
dnsserver.createSOA mname, rname, serial, refresh, retry, expire, minimum
|
||||
|
||||
exports.createServer = (domain, address = "127.0.0.1") ->
|
||||
new Server domain, address
|
||||
|
||||
exports.Subdomain = class Subdomain
|
||||
@extract: (name, domain, address) ->
|
||||
return unless name
|
||||
name = name.toLowerCase()
|
||||
offset = name.length - domain.length
|
||||
|
||||
if domain is name.slice offset
|
||||
subdomain = if 0 >= offset then null else name.slice 0, offset - 1
|
||||
new constructor subdomain, address if constructor = @for subdomain
|
||||
|
||||
@for: (subdomain = "") ->
|
||||
if IPAddressSubdomain.pattern.test subdomain
|
||||
IPAddressSubdomain
|
||||
else if EncodedSubdomain.pattern.test subdomain
|
||||
EncodedSubdomain
|
||||
else
|
||||
Subdomain
|
||||
|
||||
constructor: (@subdomain, @address) ->
|
||||
@labels = subdomain?.split(".") ? []
|
||||
@length = @labels.length
|
||||
|
||||
isEmpty: ->
|
||||
@length is 0
|
||||
|
||||
getAddress: ->
|
||||
@address
|
||||
|
||||
class IPAddressSubdomain extends Subdomain
|
||||
@pattern = /// (^|\.)
|
||||
((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
|
||||
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
|
||||
$ ///
|
||||
|
||||
getAddress: ->
|
||||
@labels.slice(-4).join "."
|
||||
|
||||
class EncodedSubdomain extends Subdomain
|
||||
@pattern = /(^|\.)[a-z0-9]{1,7}$/
|
||||
|
||||
getAddress: ->
|
||||
decode @labels[@length - 1]
|
||||
|
||||
exports.encode = encode = (ip) ->
|
||||
value = 0
|
||||
for byte, index in ip.split "."
|
||||
value += parseInt(byte, 10) << (index * 8)
|
||||
(value >>> 0).toString 36
|
||||
|
||||
PATTERN = /^[a-z0-9]{1,7}$/
|
||||
|
||||
exports.decode = decode = (string) ->
|
||||
return unless PATTERN.test string
|
||||
value = parseInt string, 36
|
||||
ip = []
|
||||
for i in [1..4]
|
||||
ip.push value & 0xFF
|
||||
value >>= 8
|
||||
ip.join "."
|
||||
419
test/fixtures/coq/interval_discr.v
vendored
419
test/fixtures/coq/interval_discr.v
vendored
@@ -1,419 +0,0 @@
|
||||
(** Sketch of the proof of {p:nat|p<=n} = {p:nat|p<=m} -> n=m
|
||||
|
||||
- preliminary results on the irrelevance of boundedness proofs
|
||||
- introduce the notion of finite cardinal |A|
|
||||
- prove that |{p:nat|p<=n}| = n
|
||||
- prove that |A| = n /\ |A| = m -> n = m if equality is decidable on A
|
||||
- prove that equality is decidable on A
|
||||
- conclude
|
||||
*)
|
||||
|
||||
(** * Preliminary results on [nat] and [le] *)
|
||||
|
||||
(** Proving axiom K on [nat] *)
|
||||
|
||||
Require Import Eqdep_dec.
|
||||
Require Import Arith.
|
||||
|
||||
Theorem eq_rect_eq_nat :
|
||||
forall (p:nat) (Q:nat->Type) (x:Q p) (h:p=p), x = eq_rect p Q x p h.
|
||||
Proof.
|
||||
intros.
|
||||
apply K_dec_set with (p := h).
|
||||
apply eq_nat_dec.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(** Proving unicity of proofs of [(n<=m)%nat] *)
|
||||
|
||||
Scheme le_ind' := Induction for le Sort Prop.
|
||||
|
||||
Theorem le_uniqueness_proof : forall (n m : nat) (p q : n <= m), p = q.
|
||||
Proof.
|
||||
induction p using le_ind'; intro q.
|
||||
replace (le_n n) with
|
||||
(eq_rect _ (fun n0 => n <= n0) (le_n n) _ (refl_equal n)).
|
||||
2:reflexivity.
|
||||
generalize (refl_equal n).
|
||||
pattern n at 2 4 6 10, q; case q; [intro | intros m l e].
|
||||
rewrite <- eq_rect_eq_nat; trivial.
|
||||
contradiction (le_Sn_n m); rewrite <- e; assumption.
|
||||
replace (le_S n m p) with
|
||||
(eq_rect _ (fun n0 => n <= n0) (le_S n m p) _ (refl_equal (S m))).
|
||||
2:reflexivity.
|
||||
generalize (refl_equal (S m)).
|
||||
pattern (S m) at 1 3 4 6, q; case q; [intro Heq | intros m0 l HeqS].
|
||||
contradiction (le_Sn_n m); rewrite Heq; assumption.
|
||||
injection HeqS; intro Heq; generalize l HeqS.
|
||||
rewrite <- Heq; intros; rewrite <- eq_rect_eq_nat.
|
||||
rewrite (IHp l0); reflexivity.
|
||||
Qed.
|
||||
|
||||
(** Proving irrelevance of boundedness proofs while building
|
||||
elements of interval *)
|
||||
|
||||
Lemma dep_pair_intro :
|
||||
forall (n x y:nat) (Hx : x<=n) (Hy : y<=n), x=y ->
|
||||
exist (fun x => x <= n) x Hx = exist (fun x => x <= n) y Hy.
|
||||
Proof.
|
||||
intros n x y Hx Hy Heq.
|
||||
generalize Hy.
|
||||
rewrite <- Heq.
|
||||
intros.
|
||||
rewrite (le_uniqueness_proof x n Hx Hy0).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(** * Proving that {p:nat|p<=n} = {p:nat|p<=m} -> n=m *)
|
||||
|
||||
(** Definition of having finite cardinality [n+1] for a set [A] *)
|
||||
|
||||
Definition card (A:Set) n :=
|
||||
exists f,
|
||||
(forall x:A, f x <= n) /\
|
||||
(forall x y:A, f x = f y -> x = y) /\
|
||||
(forall m, m <= n -> exists x:A, f x = m).
|
||||
|
||||
Require Import Arith.
|
||||
|
||||
(** Showing that the interval [0;n] has cardinality [n+1] *)
|
||||
|
||||
Theorem card_interval : forall n, card {x:nat|x<=n} n.
|
||||
Proof.
|
||||
intro n.
|
||||
exists (fun x:{x:nat|x<=n} => proj1_sig x).
|
||||
split.
|
||||
(* bounded *)
|
||||
intro x; apply (proj2_sig x).
|
||||
split.
|
||||
(* injectivity *)
|
||||
intros (p,Hp) (q,Hq).
|
||||
simpl.
|
||||
intro Hpq.
|
||||
apply dep_pair_intro; assumption.
|
||||
(* surjectivity *)
|
||||
intros m Hmn.
|
||||
exists (exist (fun x : nat => x <= n) m Hmn).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(** Showing that equality on the interval [0;n] is decidable *)
|
||||
|
||||
Lemma interval_dec :
|
||||
forall n (x y : {m:nat|m<=n}), {x=y}+{x<>y}.
|
||||
Proof.
|
||||
intros n (p,Hp).
|
||||
induction p; intros ([|q],Hq).
|
||||
left.
|
||||
apply dep_pair_intro.
|
||||
reflexivity.
|
||||
right.
|
||||
intro H; discriminate H.
|
||||
right.
|
||||
intro H; discriminate H.
|
||||
assert (Hp' : p <= n).
|
||||
apply le_Sn_le; assumption.
|
||||
assert (Hq' : q <= n).
|
||||
apply le_Sn_le; assumption.
|
||||
destruct (IHp Hp' (exist (fun m => m <= n) q Hq'))
|
||||
as [Heq|Hneq].
|
||||
left.
|
||||
injection Heq; intro Heq'.
|
||||
apply dep_pair_intro.
|
||||
apply eq_S.
|
||||
assumption.
|
||||
right.
|
||||
intro HeqS.
|
||||
injection HeqS; intro Heq.
|
||||
apply Hneq.
|
||||
apply dep_pair_intro.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
(** Showing that the cardinality relation is functional on decidable sets *)
|
||||
|
||||
Lemma card_inj_aux :
|
||||
forall (A:Type) f g n,
|
||||
(forall x:A, f x <= 0) ->
|
||||
(forall x y:A, f x = f y -> x = y) ->
|
||||
(forall m, m <= S n -> exists x:A, g x = m)
|
||||
-> False.
|
||||
Proof.
|
||||
intros A f g n Hfbound Hfinj Hgsurj.
|
||||
destruct (Hgsurj (S n) (le_n _)) as (x,Hx).
|
||||
destruct (Hgsurj n (le_S _ _ (le_n _))) as (x',Hx').
|
||||
assert (Hfx : 0 = f x).
|
||||
apply le_n_O_eq.
|
||||
apply Hfbound.
|
||||
assert (Hfx' : 0 = f x').
|
||||
apply le_n_O_eq.
|
||||
apply Hfbound.
|
||||
assert (x=x').
|
||||
apply Hfinj.
|
||||
rewrite <- Hfx.
|
||||
rewrite <- Hfx'.
|
||||
reflexivity.
|
||||
rewrite H in Hx.
|
||||
rewrite Hx' in Hx.
|
||||
apply (n_Sn _ Hx).
|
||||
Qed.
|
||||
|
||||
(** For [dec_restrict], we use a lemma on the negation of equality
|
||||
that requires proof-irrelevance. It should be possible to avoid this
|
||||
lemma by generalizing over a first-order definition of [x<>y], say
|
||||
[neq] such that [{x=y}+{neq x y}] and [~(x=y /\ neq x y)]; for such
|
||||
[neq], unicity of proofs could be proven *)
|
||||
|
||||
Require Import Classical.
|
||||
Lemma neq_dep_intro :
|
||||
forall (A:Set) (z x y:A) (p:x<>z) (q:y<>z), x=y ->
|
||||
exist (fun x => x <> z) x p = exist (fun x => x <> z) y q.
|
||||
Proof.
|
||||
intros A z x y p q Heq.
|
||||
generalize q; clear q; rewrite <- Heq; intro q.
|
||||
rewrite (proof_irrelevance _ p q); reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma dec_restrict :
|
||||
forall (A:Set),
|
||||
(forall x y :A, {x=y}+{x<>y}) ->
|
||||
forall z (x y :{a:A|a<>z}), {x=y}+{x<>y}.
|
||||
Proof.
|
||||
intros A Hdec z (x,Hx) (y,Hy).
|
||||
destruct (Hdec x y) as [Heq|Hneq].
|
||||
left; apply neq_dep_intro; assumption.
|
||||
right; intro Heq; injection Heq; exact Hneq.
|
||||
Qed.
|
||||
|
||||
Lemma pred_inj : forall n m,
|
||||
0 <> n -> 0 <> m -> pred m = pred n -> m = n.
|
||||
Proof.
|
||||
destruct n.
|
||||
intros m H; destruct H; reflexivity.
|
||||
destruct m.
|
||||
intros _ H; destruct H; reflexivity.
|
||||
simpl; intros _ _ H.
|
||||
rewrite H.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma le_neq_lt : forall n m, n <= m -> n<>m -> n < m.
|
||||
Proof.
|
||||
intros n m Hle Hneq.
|
||||
destruct (le_lt_eq_dec n m Hle).
|
||||
assumption.
|
||||
contradiction.
|
||||
Qed.
|
||||
|
||||
Lemma inj_restrict :
|
||||
forall (A:Set) (f:A->nat) x y z,
|
||||
(forall x y : A, f x = f y -> x = y)
|
||||
-> x <> z -> f y < f z -> f z <= f x
|
||||
-> pred (f x) = f y
|
||||
-> False.
|
||||
|
||||
(* Search error sans le type de f !! *)
|
||||
Proof.
|
||||
intros A f x y z Hfinj Hneqx Hfy Hfx Heq.
|
||||
assert (f z <> f x).
|
||||
apply sym_not_eq.
|
||||
intro Heqf.
|
||||
apply Hneqx.
|
||||
apply Hfinj.
|
||||
assumption.
|
||||
assert (f x = S (f y)).
|
||||
assert (0 < f x).
|
||||
apply le_lt_trans with (f z).
|
||||
apply le_O_n.
|
||||
apply le_neq_lt; assumption.
|
||||
apply pred_inj.
|
||||
apply O_S.
|
||||
apply lt_O_neq; assumption.
|
||||
exact Heq.
|
||||
assert (f z <= f y).
|
||||
destruct (le_lt_or_eq _ _ Hfx).
|
||||
apply lt_n_Sm_le.
|
||||
rewrite <- H0.
|
||||
assumption.
|
||||
contradiction Hneqx.
|
||||
symmetry.
|
||||
apply Hfinj.
|
||||
assumption.
|
||||
contradiction (lt_not_le (f y) (f z)).
|
||||
Qed.
|
||||
|
||||
Theorem card_inj : forall m n (A:Set),
|
||||
(forall x y :A, {x=y}+{x<>y}) ->
|
||||
card A m -> card A n -> m = n.
|
||||
Proof.
|
||||
induction m; destruct n;
|
||||
intros A Hdec
|
||||
(f,(Hfbound,(Hfinj,Hfsurj)))
|
||||
(g,(Hgbound,(Hginj,Hgsurj))).
|
||||
(* 0/0 *)
|
||||
reflexivity.
|
||||
(* 0/Sm *)
|
||||
destruct (card_inj_aux _ _ _ _ Hfbound Hfinj Hgsurj).
|
||||
(* Sn/0 *)
|
||||
destruct (card_inj_aux _ _ _ _ Hgbound Hginj Hfsurj).
|
||||
(* Sn/Sm *)
|
||||
destruct (Hgsurj (S n) (le_n _)) as (xSn,HSnx).
|
||||
rewrite IHm with (n:=n) (A := {x:A|x<>xSn}).
|
||||
reflexivity.
|
||||
(* decidability of eq on {x:A|x<>xSm} *)
|
||||
apply dec_restrict.
|
||||
assumption.
|
||||
(* cardinality of {x:A|x<>xSn} is m *)
|
||||
pose (f' := fun x' : {x:A|x<>xSn} =>
|
||||
let (x,Hneq) := x' in
|
||||
if le_lt_dec (f xSn) (f x)
|
||||
then pred (f x)
|
||||
else f x).
|
||||
exists f'.
|
||||
split.
|
||||
(* f' is bounded *)
|
||||
unfold f'.
|
||||
intros (x,_).
|
||||
destruct (le_lt_dec (f xSn) (f x)) as [Hle|Hge].
|
||||
change m with (pred (S m)).
|
||||
apply le_pred.
|
||||
apply Hfbound.
|
||||
apply le_S_n.
|
||||
apply le_trans with (f xSn).
|
||||
exact Hge.
|
||||
apply Hfbound.
|
||||
split.
|
||||
(* f' is injective *)
|
||||
unfold f'.
|
||||
intros (x,Hneqx) (y,Hneqy) Heqf'.
|
||||
destruct (le_lt_dec (f xSn) (f x)) as [Hlefx|Hgefx];
|
||||
destruct (le_lt_dec (f xSn) (f y)) as [Hlefy|Hgefy].
|
||||
(* f xSn <= f x et f xSn <= f y *)
|
||||
assert (Heq : x = y).
|
||||
apply Hfinj.
|
||||
assert (f xSn <> f y).
|
||||
apply sym_not_eq.
|
||||
intro Heqf.
|
||||
apply Hneqy.
|
||||
apply Hfinj.
|
||||
assumption.
|
||||
assert (0 < f y).
|
||||
apply le_lt_trans with (f xSn).
|
||||
apply le_O_n.
|
||||
apply le_neq_lt; assumption.
|
||||
assert (f xSn <> f x).
|
||||
apply sym_not_eq.
|
||||
intro Heqf.
|
||||
apply Hneqx.
|
||||
apply Hfinj.
|
||||
assumption.
|
||||
assert (0 < f x).
|
||||
apply le_lt_trans with (f xSn).
|
||||
apply le_O_n.
|
||||
apply le_neq_lt; assumption.
|
||||
apply pred_inj.
|
||||
apply lt_O_neq; assumption.
|
||||
apply lt_O_neq; assumption.
|
||||
assumption.
|
||||
apply neq_dep_intro; assumption.
|
||||
(* f y < f xSn <= f x *)
|
||||
destruct (inj_restrict A f x y xSn); assumption.
|
||||
(* f x < f xSn <= f y *)
|
||||
symmetry in Heqf'.
|
||||
destruct (inj_restrict A f y x xSn); assumption.
|
||||
(* f x < f xSn et f y < f xSn *)
|
||||
assert (Heq : x=y).
|
||||
apply Hfinj; assumption.
|
||||
apply neq_dep_intro; assumption.
|
||||
(* f' is surjective *)
|
||||
intros p Hlep.
|
||||
destruct (le_lt_dec (f xSn) p) as [Hle|Hlt].
|
||||
(* case f xSn <= p *)
|
||||
destruct (Hfsurj (S p) (le_n_S _ _ Hlep)) as (x,Hx).
|
||||
assert (Hneq : x <> xSn).
|
||||
intro Heqx.
|
||||
rewrite Heqx in Hx.
|
||||
rewrite Hx in Hle.
|
||||
apply le_Sn_n with p; assumption.
|
||||
exists (exist (fun a => a<>xSn) x Hneq).
|
||||
unfold f'.
|
||||
destruct (le_lt_dec (f xSn) (f x)) as [Hle'|Hlt'].
|
||||
rewrite Hx; reflexivity.
|
||||
rewrite Hx in Hlt'.
|
||||
contradiction (le_not_lt (f xSn) p).
|
||||
apply lt_trans with (S p).
|
||||
apply lt_n_Sn.
|
||||
assumption.
|
||||
(* case p < f xSn *)
|
||||
destruct (Hfsurj p (le_S _ _ Hlep)) as (x,Hx).
|
||||
assert (Hneq : x <> xSn).
|
||||
intro Heqx.
|
||||
rewrite Heqx in Hx.
|
||||
rewrite Hx in Hlt.
|
||||
apply (lt_irrefl p).
|
||||
assumption.
|
||||
exists (exist (fun a => a<>xSn) x Hneq).
|
||||
unfold f'.
|
||||
destruct (le_lt_dec (f xSn) (f x)) as [Hle'|Hlt'].
|
||||
rewrite Hx in Hle'.
|
||||
contradiction (lt_irrefl p).
|
||||
apply lt_le_trans with (f xSn); assumption.
|
||||
assumption.
|
||||
(* cardinality of {x:A|x<>xSn} is n *)
|
||||
pose (g' := fun x' : {x:A|x<>xSn} =>
|
||||
let (x,Hneq) := x' in
|
||||
if Hdec x xSn then 0 else g x).
|
||||
exists g'.
|
||||
split.
|
||||
(* g is bounded *)
|
||||
unfold g'.
|
||||
intros (x,_).
|
||||
destruct (Hdec x xSn) as [_|Hneq].
|
||||
apply le_O_n.
|
||||
assert (Hle_gx:=Hgbound x).
|
||||
destruct (le_lt_or_eq _ _ Hle_gx).
|
||||
apply lt_n_Sm_le.
|
||||
assumption.
|
||||
contradiction Hneq.
|
||||
apply Hginj.
|
||||
rewrite HSnx.
|
||||
assumption.
|
||||
split.
|
||||
(* g is injective *)
|
||||
unfold g'.
|
||||
intros (x,Hneqx) (y,Hneqy) Heqg'.
|
||||
destruct (Hdec x xSn) as [Heqx|_].
|
||||
contradiction Hneqx.
|
||||
destruct (Hdec y xSn) as [Heqy|_].
|
||||
contradiction Hneqy.
|
||||
assert (Heq : x=y).
|
||||
apply Hginj; assumption.
|
||||
apply neq_dep_intro; assumption.
|
||||
(* g is surjective *)
|
||||
intros p Hlep.
|
||||
destruct (Hgsurj p (le_S _ _ Hlep)) as (x,Hx).
|
||||
assert (Hneq : x<>xSn).
|
||||
intro Heq.
|
||||
rewrite Heq in Hx.
|
||||
rewrite Hx in HSnx.
|
||||
rewrite HSnx in Hlep.
|
||||
contradiction (le_Sn_n _ Hlep).
|
||||
exists (exist (fun a => a<>xSn) x Hneq).
|
||||
simpl.
|
||||
destruct (Hdec x xSn) as [Heqx|_].
|
||||
contradiction Hneq.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
(** Conclusion *)
|
||||
|
||||
Theorem interval_discr :
|
||||
forall n m, {p:nat|p<=n} = {p:nat|p<=m} -> n=m.
|
||||
Proof.
|
||||
intros n m Heq.
|
||||
apply card_inj with (A := {p:nat|p<=n}).
|
||||
apply interval_dec.
|
||||
apply card_interval.
|
||||
rewrite Heq.
|
||||
apply card_interval.
|
||||
Qed.
|
||||
10
test/fixtures/cpp/bar.h
vendored
10
test/fixtures/cpp/bar.h
vendored
@@ -1,10 +0,0 @@
|
||||
class Bar
|
||||
{
|
||||
protected:
|
||||
|
||||
char *name;
|
||||
|
||||
public:
|
||||
|
||||
void hello();
|
||||
}
|
||||
10
test/fixtures/cpp/bar.hpp
vendored
10
test/fixtures/cpp/bar.hpp
vendored
@@ -1,10 +0,0 @@
|
||||
class Bar
|
||||
{
|
||||
protected:
|
||||
|
||||
char *name;
|
||||
|
||||
public:
|
||||
|
||||
void hello();
|
||||
}
|
||||
39
test/fixtures/cpp/cuda.cu
vendored
39
test/fixtures/cpp/cuda.cu
vendored
@@ -1,39 +0,0 @@
|
||||
void foo()
|
||||
{
|
||||
cudaArray* cu_array;
|
||||
texture<float, 2, cudaReadModeElementType> tex;
|
||||
|
||||
// Allocate array
|
||||
cudaChannelFormatDesc description = cudaCreateChannelDesc<float>();
|
||||
cudaMallocArray(&cu_array, &description, width, height);
|
||||
|
||||
// Copy image data to array
|
||||
cudaMemcpyToArray(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
|
||||
|
||||
// Set texture parameters (default)
|
||||
tex.addressMode[0] = cudaAddressModeClamp;
|
||||
tex.addressMode[1] = cudaAddressModeClamp;
|
||||
tex.filterMode = cudaFilterModePoint;
|
||||
tex.normalized = false; // do not normalize coordinates
|
||||
|
||||
// Bind the array to the texture
|
||||
cudaBindTextureToArray(tex, cu_array);
|
||||
|
||||
// Run kernel
|
||||
dim3 blockDim(16, 16, 1);
|
||||
dim3 gridDim((width + blockDim.x - 1)/ blockDim.x, (height + blockDim.y - 1) / blockDim.y, 1);
|
||||
kernel<<< gridDim, blockDim, 0 >>>(d_data, height, width);
|
||||
|
||||
// Unbind the array from the texture
|
||||
cudaUnbindTexture(tex);
|
||||
} //end foo()
|
||||
|
||||
__global__ void kernel(float* odata, int height, int width)
|
||||
{
|
||||
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
|
||||
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
|
||||
if (x < width && y < height) {
|
||||
float c = tex2D(tex, x, y);
|
||||
odata[y*width+x] = c;
|
||||
}
|
||||
}
|
||||
81
test/fixtures/cpp/env.cpp
vendored
81
test/fixtures/cpp/env.cpp
vendored
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2012 execjosh, http://execjosh.blogspot.com
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "env.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
|
||||
static Env *env_instance = (Env *)NULL;
|
||||
|
||||
Env *Env::instance()
|
||||
{
|
||||
if ((Env *)NULL == env_instance)
|
||||
env_instance = new Env();
|
||||
|
||||
return env_instance;
|
||||
}
|
||||
|
||||
Env::Env()
|
||||
: QObject(QCoreApplication::instance())
|
||||
{
|
||||
}
|
||||
|
||||
// public:
|
||||
|
||||
void Env::parse(const char **envp)
|
||||
{
|
||||
const char **env = (const char **)NULL;
|
||||
QString envvar, name, value;
|
||||
int indexOfEquals;
|
||||
// Loop for each of the <NAME>=<VALUE> pairs and split them into a map
|
||||
for (env = envp; *env != (const char *)NULL; env++) {
|
||||
envvar = QString(*env);
|
||||
indexOfEquals = envvar.indexOf('=');
|
||||
if (0 >= indexOfEquals) {
|
||||
// Should never happen because names cannot contain "=" and cannot
|
||||
// be empty. If it does happen, then just ignore this record.
|
||||
// See: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
|
||||
continue;
|
||||
}
|
||||
// Extract name and value (if it exists) from envvar
|
||||
// NOTE:
|
||||
// QString::mid() will gracefully return an empty QString when the
|
||||
// specified position index is >= the length() of the string
|
||||
name = envvar.left(indexOfEquals);
|
||||
value = envvar.mid(indexOfEquals + 1);
|
||||
m_map.insert(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap Env::asVariantMap() const
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
52
test/fixtures/cpp/env.h
vendored
52
test/fixtures/cpp/env.h
vendored
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2012 execjosh, http://execjosh.blogspot.com
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ENV_H
|
||||
#define ENV_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class Env : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static Env *instance();
|
||||
|
||||
void parse(const char ** envp);
|
||||
QVariantMap asVariantMap() const;
|
||||
|
||||
private:
|
||||
Env();
|
||||
|
||||
QVariantMap m_map;
|
||||
};
|
||||
|
||||
#endif // ENV_H
|
||||
8
test/fixtures/cpp/hello.cpp
vendored
8
test/fixtures/cpp/hello.cpp
vendored
@@ -1,8 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "Hello World" << endl;
|
||||
}
|
||||
382
test/fixtures/cpp/key.cpp
vendored
382
test/fixtures/cpp/key.cpp
vendored
@@ -1,382 +0,0 @@
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
|
||||
#include "key.h"
|
||||
|
||||
// Generate a private key from just the secret parameter
|
||||
int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey) return 0;
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
pub_key = EC_POINT_new(group);
|
||||
|
||||
if (pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
goto err;
|
||||
|
||||
EC_KEY_set_private_key(eckey,priv_key);
|
||||
EC_KEY_set_public_key(eckey,pub_key);
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
|
||||
if (pub_key)
|
||||
EC_POINT_free(pub_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return(ok);
|
||||
}
|
||||
|
||||
// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
|
||||
// recid selects which key is recovered
|
||||
// if check is nonzero, additional checks are performed
|
||||
int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
|
||||
{
|
||||
if (!eckey) return 0;
|
||||
|
||||
int ret = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
BIGNUM *x = NULL;
|
||||
BIGNUM *e = NULL;
|
||||
BIGNUM *order = NULL;
|
||||
BIGNUM *sor = NULL;
|
||||
BIGNUM *eor = NULL;
|
||||
BIGNUM *field = NULL;
|
||||
EC_POINT *R = NULL;
|
||||
EC_POINT *O = NULL;
|
||||
EC_POINT *Q = NULL;
|
||||
BIGNUM *rr = NULL;
|
||||
BIGNUM *zero = NULL;
|
||||
int n = 0;
|
||||
int i = recid / 2;
|
||||
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
|
||||
BN_CTX_start(ctx);
|
||||
order = BN_CTX_get(ctx);
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
|
||||
x = BN_CTX_get(ctx);
|
||||
if (!BN_copy(x, order)) { ret=-1; goto err; }
|
||||
if (!BN_mul_word(x, i)) { ret=-1; goto err; }
|
||||
if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
|
||||
field = BN_CTX_get(ctx);
|
||||
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
|
||||
if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
|
||||
if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
|
||||
if (check)
|
||||
{
|
||||
if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
|
||||
if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
|
||||
}
|
||||
if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
|
||||
n = EC_GROUP_get_degree(group);
|
||||
e = BN_CTX_get(ctx);
|
||||
if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
|
||||
if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
|
||||
zero = BN_CTX_get(ctx);
|
||||
if (!BN_zero(zero)) { ret=-1; goto err; }
|
||||
if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
|
||||
rr = BN_CTX_get(ctx);
|
||||
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
|
||||
sor = BN_CTX_get(ctx);
|
||||
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
|
||||
eor = BN_CTX_get(ctx);
|
||||
if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
|
||||
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
|
||||
if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx) {
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
if (R != NULL) EC_POINT_free(R);
|
||||
if (O != NULL) EC_POINT_free(O);
|
||||
if (Q != NULL) EC_POINT_free(Q);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CKey::SetCompressedPubKey()
|
||||
{
|
||||
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
|
||||
fCompressedPubKey = true;
|
||||
}
|
||||
|
||||
void CKey::Reset()
|
||||
{
|
||||
fCompressedPubKey = false;
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
|
||||
fSet = false;
|
||||
}
|
||||
|
||||
CKey::CKey()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
CKey::CKey(const CKey& b)
|
||||
{
|
||||
pkey = EC_KEY_dup(b.pkey);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
|
||||
fSet = b.fSet;
|
||||
}
|
||||
|
||||
CKey& CKey::operator=(const CKey& b)
|
||||
{
|
||||
if (!EC_KEY_copy(pkey, b.pkey))
|
||||
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
|
||||
fSet = b.fSet;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
CKey::~CKey()
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
|
||||
bool CKey::IsNull() const
|
||||
{
|
||||
return !fSet;
|
||||
}
|
||||
|
||||
bool CKey::IsCompressed() const
|
||||
{
|
||||
return fCompressedPubKey;
|
||||
}
|
||||
|
||||
void CKey::MakeNewKey(bool fCompressed)
|
||||
{
|
||||
if (!EC_KEY_generate_key(pkey))
|
||||
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
|
||||
if (fCompressed)
|
||||
SetCompressedPubKey();
|
||||
fSet = true;
|
||||
}
|
||||
|
||||
bool CKey::SetPrivKey(const CPrivKey& vchPrivKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed)
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (pkey == NULL)
|
||||
throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
|
||||
if (vchSecret.size() != 32)
|
||||
throw key_error("CKey::SetSecret() : secret must be 32 bytes");
|
||||
BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::SetSecret() : BN_bin2bn failed");
|
||||
if (!EC_KEY_regenerate_key(pkey,bn))
|
||||
{
|
||||
BN_clear_free(bn);
|
||||
throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
|
||||
}
|
||||
BN_clear_free(bn);
|
||||
fSet = true;
|
||||
if (fCompressed || fCompressedPubKey)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
CSecret CKey::GetSecret(bool &fCompressed) const
|
||||
{
|
||||
CSecret vchRet;
|
||||
vchRet.resize(32);
|
||||
const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
|
||||
int nBytes = BN_num_bytes(bn);
|
||||
if (bn == NULL)
|
||||
throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
|
||||
int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
|
||||
if (n != nBytes)
|
||||
throw key_error("CKey::GetSecret(): BN_bn2bin failed");
|
||||
fCompressed = fCompressedPubKey;
|
||||
return vchRet;
|
||||
}
|
||||
|
||||
CPrivKey CKey::GetPrivKey() const
|
||||
{
|
||||
int nSize = i2d_ECPrivateKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
||||
CPrivKey vchPrivKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPrivKey[0];
|
||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
||||
return vchPrivKey;
|
||||
}
|
||||
|
||||
bool CKey::SetPubKey(const CPubKey& vchPubKey)
|
||||
{
|
||||
const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
|
||||
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
|
||||
return false;
|
||||
fSet = true;
|
||||
if (vchPubKey.vchPubKey.size() == 33)
|
||||
SetCompressedPubKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
CPubKey CKey::GetPubKey() const
|
||||
{
|
||||
int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||
if (!nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||
std::vector<unsigned char> vchPubKey(nSize, 0);
|
||||
unsigned char* pbegin = &vchPubKey[0];
|
||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||
return CPubKey(vchPubKey);
|
||||
}
|
||||
|
||||
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
unsigned int nSize = ECDSA_size(pkey);
|
||||
vchSig.resize(nSize); // Make sure it is big enough
|
||||
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
|
||||
{
|
||||
vchSig.clear();
|
||||
return false;
|
||||
}
|
||||
vchSig.resize(nSize); // Shrink to fit actual size
|
||||
return true;
|
||||
}
|
||||
|
||||
// create a compact signature (65 bytes), which allows reconstructing the used public key
|
||||
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
|
||||
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
|
||||
// 0x1D = second key with even y, 0x1E = second key with odd y
|
||||
bool CKey::SignCompact(uint256 hash, std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
bool fOk = false;
|
||||
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
|
||||
if (sig==NULL)
|
||||
return false;
|
||||
vchSig.clear();
|
||||
vchSig.resize(65,0);
|
||||
int nBitsR = BN_num_bits(sig->r);
|
||||
int nBitsS = BN_num_bits(sig->s);
|
||||
if (nBitsR <= 256 && nBitsS <= 256)
|
||||
{
|
||||
int nRecId = -1;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
CKey keyRec;
|
||||
keyRec.fSet = true;
|
||||
if (fCompressedPubKey)
|
||||
keyRec.SetCompressedPubKey();
|
||||
if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1)
|
||||
if (keyRec.GetPubKey() == this->GetPubKey())
|
||||
{
|
||||
nRecId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nRecId == -1)
|
||||
throw key_error("CKey::SignCompact() : unable to construct recoverable key");
|
||||
|
||||
vchSig[0] = nRecId+27+(fCompressedPubKey ? 4 : 0);
|
||||
BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]);
|
||||
BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]);
|
||||
fOk = true;
|
||||
}
|
||||
ECDSA_SIG_free(sig);
|
||||
return fOk;
|
||||
}
|
||||
|
||||
// reconstruct public key from a compact signature
|
||||
// This is only slightly more CPU intensive than just verifying it.
|
||||
// If this function succeeds, the recovered public key is guaranteed to be valid
|
||||
// (the signature is a valid signature of the given data for that key)
|
||||
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
if (vchSig.size() != 65)
|
||||
return false;
|
||||
int nV = vchSig[0];
|
||||
if (nV<27 || nV>=35)
|
||||
return false;
|
||||
ECDSA_SIG *sig = ECDSA_SIG_new();
|
||||
BN_bin2bn(&vchSig[1],32,sig->r);
|
||||
BN_bin2bn(&vchSig[33],32,sig->s);
|
||||
|
||||
EC_KEY_free(pkey);
|
||||
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if (nV >= 31)
|
||||
{
|
||||
SetCompressedPubKey();
|
||||
nV -= 4;
|
||||
}
|
||||
if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
|
||||
{
|
||||
fSet = true;
|
||||
ECDSA_SIG_free(sig);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig)
|
||||
{
|
||||
CKey key;
|
||||
if (!key.SetCompactSignature(hash, vchSig))
|
||||
return false;
|
||||
if (GetPubKey() != key.GetPubKey())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKey::IsValid()
|
||||
{
|
||||
if (!fSet)
|
||||
return false;
|
||||
|
||||
bool fCompr;
|
||||
CSecret secret = GetSecret(fCompr);
|
||||
CKey key2;
|
||||
key2.SetSecret(secret, fCompr);
|
||||
return GetPubKey() == key2.GetPubKey();
|
||||
}
|
||||
162
test/fixtures/cpp/key.h
vendored
162
test/fixtures/cpp/key.h
vendored
@@ -1,162 +0,0 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef BITCOIN_KEY_H
|
||||
#define BITCOIN_KEY_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include "allocators.h"
|
||||
#include "serialize.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <openssl/ec.h> // for EC_KEY definition
|
||||
|
||||
// secp160k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 192;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 41;
|
||||
// const unsigned int SIGNATURE_SIZE = 48;
|
||||
//
|
||||
// secp192k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 222;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 49;
|
||||
// const unsigned int SIGNATURE_SIZE = 57;
|
||||
//
|
||||
// secp224k1
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 250;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 57;
|
||||
// const unsigned int SIGNATURE_SIZE = 66;
|
||||
//
|
||||
// secp256k1:
|
||||
// const unsigned int PRIVATE_KEY_SIZE = 279;
|
||||
// const unsigned int PUBLIC_KEY_SIZE = 65;
|
||||
// const unsigned int SIGNATURE_SIZE = 72;
|
||||
//
|
||||
// see www.keylength.com
|
||||
// script supports up to 75 for single byte push
|
||||
|
||||
class key_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit key_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
/** A reference to a CKey: the Hash160 of its serialized public key */
|
||||
class CKeyID : public uint160
|
||||
{
|
||||
public:
|
||||
CKeyID() : uint160(0) { }
|
||||
CKeyID(const uint160 &in) : uint160(in) { }
|
||||
};
|
||||
|
||||
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
||||
class CScriptID : public uint160
|
||||
{
|
||||
public:
|
||||
CScriptID() : uint160(0) { }
|
||||
CScriptID(const uint160 &in) : uint160(in) { }
|
||||
};
|
||||
|
||||
/** An encapsulated public key. */
|
||||
class CPubKey {
|
||||
private:
|
||||
std::vector<unsigned char> vchPubKey;
|
||||
friend class CKey;
|
||||
|
||||
public:
|
||||
CPubKey() { }
|
||||
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
|
||||
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
|
||||
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
|
||||
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
|
||||
|
||||
IMPLEMENT_SERIALIZE(
|
||||
READWRITE(vchPubKey);
|
||||
)
|
||||
|
||||
CKeyID GetID() const {
|
||||
return CKeyID(Hash160(vchPubKey));
|
||||
}
|
||||
|
||||
uint256 GetHash() const {
|
||||
return Hash(vchPubKey.begin(), vchPubKey.end());
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
|
||||
}
|
||||
|
||||
bool IsCompressed() const {
|
||||
return vchPubKey.size() == 33;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Raw() const {
|
||||
return vchPubKey;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// secure_allocator is defined in serialize.h
|
||||
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
||||
// CSecret is a serialization of just the secret parameter (32 bytes)
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
|
||||
|
||||
/** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
|
||||
class CKey
|
||||
{
|
||||
protected:
|
||||
EC_KEY* pkey;
|
||||
bool fSet;
|
||||
bool fCompressedPubKey;
|
||||
|
||||
void SetCompressedPubKey();
|
||||
|
||||
public:
|
||||
|
||||
void Reset();
|
||||
|
||||
CKey();
|
||||
CKey(const CKey& b);
|
||||
|
||||
CKey& operator=(const CKey& b);
|
||||
|
||||
~CKey();
|
||||
|
||||
bool IsNull() const;
|
||||
bool IsCompressed() const;
|
||||
|
||||
void MakeNewKey(bool fCompressed);
|
||||
bool SetPrivKey(const CPrivKey& vchPrivKey);
|
||||
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
|
||||
CSecret GetSecret(bool &fCompressed) const;
|
||||
CPrivKey GetPrivKey() const;
|
||||
bool SetPubKey(const CPubKey& vchPubKey);
|
||||
CPubKey GetPubKey() const;
|
||||
|
||||
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||
|
||||
// create a compact signature (65 bytes), which allows reconstructing the used public key
|
||||
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
|
||||
// The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
|
||||
// 0x1D = second key with even y, 0x1E = second key with odd y
|
||||
bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
|
||||
|
||||
// reconstruct public key from a compact signature
|
||||
// This is only slightly more CPU intensive than just verifying it.
|
||||
// If this function succeeds, the recovered public key is guaranteed to be valid
|
||||
// (the signature is a valid signature of the given data for that key)
|
||||
bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
// Verify a compact signature
|
||||
bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
|
||||
|
||||
bool IsValid();
|
||||
};
|
||||
|
||||
#endif
|
||||
74
test/fixtures/cpp/main.cpp
vendored
74
test/fixtures/cpp/main.cpp
vendored
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "consts.h"
|
||||
#include "utils.h"
|
||||
#include "env.h"
|
||||
#include "phantom.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "client/linux/handler/exception_handler.h"
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#if QT_VERSION != QT_VERSION_CHECK(4, 8, 0)
|
||||
#error Something is wrong with the setup. Please report to the mailing list!
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv, const char** envp)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
google_breakpad::ExceptionHandler eh("/tmp", NULL, Utils::exceptionHandler, NULL, true);
|
||||
#endif
|
||||
|
||||
// Registering an alternative Message Handler
|
||||
qInstallMsgHandler(Utils::messageHandler);
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
#ifdef STATIC_BUILD
|
||||
Q_INIT_RESOURCE(WebKit);
|
||||
Q_INIT_RESOURCE(InspectorBackendStub);
|
||||
#endif
|
||||
|
||||
app.setWindowIcon(QIcon(":/phantomjs-icon.png"));
|
||||
app.setApplicationName("PhantomJS");
|
||||
app.setOrganizationName("Ofi Labs");
|
||||
app.setOrganizationDomain("www.ofilabs.com");
|
||||
app.setApplicationVersion(PHANTOMJS_VERSION_STRING);
|
||||
|
||||
Env::instance()->parse(envp);
|
||||
|
||||
Phantom phantom;
|
||||
if (phantom.execute()) {
|
||||
app.exec();
|
||||
}
|
||||
return phantom.returnValue();
|
||||
}
|
||||
1088
test/fixtures/cpp/scanner.cc
vendored
1088
test/fixtures/cpp/scanner.cc
vendored
File diff suppressed because it is too large
Load Diff
576
test/fixtures/cpp/scanner.h
vendored
576
test/fixtures/cpp/scanner.h
vendored
@@ -1,576 +0,0 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Features shared by parsing and pre-parsing scanners.
|
||||
|
||||
#ifndef V8_SCANNER_H_
|
||||
#define V8_SCANNER_H_
|
||||
|
||||
#include "allocation.h"
|
||||
#include "char-predicates.h"
|
||||
#include "checks.h"
|
||||
#include "globals.h"
|
||||
#include "token.h"
|
||||
#include "unicode-inl.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
// General collection of (multi-)bit-flags that can be passed to scanners and
|
||||
// parsers to signify their (initial) mode of operation.
|
||||
enum ParsingFlags {
|
||||
kNoParsingFlags = 0,
|
||||
// Embed LanguageMode values in parsing flags, i.e., equivalent to:
|
||||
// CLASSIC_MODE = 0,
|
||||
// STRICT_MODE,
|
||||
// EXTENDED_MODE,
|
||||
kLanguageModeMask = 0x03,
|
||||
kAllowLazy = 0x04,
|
||||
kAllowNativesSyntax = 0x08,
|
||||
kAllowModules = 0x10
|
||||
};
|
||||
|
||||
STATIC_ASSERT((kLanguageModeMask & CLASSIC_MODE) == CLASSIC_MODE);
|
||||
STATIC_ASSERT((kLanguageModeMask & STRICT_MODE) == STRICT_MODE);
|
||||
STATIC_ASSERT((kLanguageModeMask & EXTENDED_MODE) == EXTENDED_MODE);
|
||||
|
||||
|
||||
// Returns the value (0 .. 15) of a hexadecimal character c.
|
||||
// If c is not a legal hexadecimal character, returns a value < 0.
|
||||
inline int HexValue(uc32 c) {
|
||||
c -= '0';
|
||||
if (static_cast<unsigned>(c) <= 9) return c;
|
||||
c = (c | 0x20) - ('a' - '0'); // detect 0x11..0x16 and 0x31..0x36.
|
||||
if (static_cast<unsigned>(c) <= 5) return c + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Buffered stream of UTF-16 code units, using an internal UTF-16 buffer.
|
||||
// A code unit is a 16 bit value representing either a 16 bit code point
|
||||
// or one part of a surrogate pair that make a single 21 bit code point.
|
||||
|
||||
class Utf16CharacterStream {
|
||||
public:
|
||||
Utf16CharacterStream() : pos_(0) { }
|
||||
virtual ~Utf16CharacterStream() { }
|
||||
|
||||
// Returns and advances past the next UTF-16 code unit in the input
|
||||
// stream. If there are no more code units, it returns a negative
|
||||
// value.
|
||||
inline uc32 Advance() {
|
||||
if (buffer_cursor_ < buffer_end_ || ReadBlock()) {
|
||||
pos_++;
|
||||
return static_cast<uc32>(*(buffer_cursor_++));
|
||||
}
|
||||
// Note: currently the following increment is necessary to avoid a
|
||||
// parser problem! The scanner treats the final kEndOfInput as
|
||||
// a code unit with a position, and does math relative to that
|
||||
// position.
|
||||
pos_++;
|
||||
|
||||
return kEndOfInput;
|
||||
}
|
||||
|
||||
// Return the current position in the code unit stream.
|
||||
// Starts at zero.
|
||||
inline unsigned pos() const { return pos_; }
|
||||
|
||||
// Skips forward past the next code_unit_count UTF-16 code units
|
||||
// in the input, or until the end of input if that comes sooner.
|
||||
// Returns the number of code units actually skipped. If less
|
||||
// than code_unit_count,
|
||||
inline unsigned SeekForward(unsigned code_unit_count) {
|
||||
unsigned buffered_chars =
|
||||
static_cast<unsigned>(buffer_end_ - buffer_cursor_);
|
||||
if (code_unit_count <= buffered_chars) {
|
||||
buffer_cursor_ += code_unit_count;
|
||||
pos_ += code_unit_count;
|
||||
return code_unit_count;
|
||||
}
|
||||
return SlowSeekForward(code_unit_count);
|
||||
}
|
||||
|
||||
// Pushes back the most recently read UTF-16 code unit (or negative
|
||||
// value if at end of input), i.e., the value returned by the most recent
|
||||
// call to Advance.
|
||||
// Must not be used right after calling SeekForward.
|
||||
virtual void PushBack(int32_t code_unit) = 0;
|
||||
|
||||
protected:
|
||||
static const uc32 kEndOfInput = -1;
|
||||
|
||||
// Ensures that the buffer_cursor_ points to the code_unit at
|
||||
// position pos_ of the input, if possible. If the position
|
||||
// is at or after the end of the input, return false. If there
|
||||
// are more code_units available, return true.
|
||||
virtual bool ReadBlock() = 0;
|
||||
virtual unsigned SlowSeekForward(unsigned code_unit_count) = 0;
|
||||
|
||||
const uc16* buffer_cursor_;
|
||||
const uc16* buffer_end_;
|
||||
unsigned pos_;
|
||||
};
|
||||
|
||||
|
||||
class UnicodeCache {
|
||||
// ---------------------------------------------------------------------
|
||||
// Caching predicates used by scanners.
|
||||
public:
|
||||
UnicodeCache() {}
|
||||
typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
|
||||
|
||||
StaticResource<Utf8Decoder>* utf8_decoder() {
|
||||
return &utf8_decoder_;
|
||||
}
|
||||
|
||||
bool IsIdentifierStart(unibrow::uchar c) { return kIsIdentifierStart.get(c); }
|
||||
bool IsIdentifierPart(unibrow::uchar c) { return kIsIdentifierPart.get(c); }
|
||||
bool IsLineTerminator(unibrow::uchar c) { return kIsLineTerminator.get(c); }
|
||||
bool IsWhiteSpace(unibrow::uchar c) { return kIsWhiteSpace.get(c); }
|
||||
|
||||
private:
|
||||
unibrow::Predicate<IdentifierStart, 128> kIsIdentifierStart;
|
||||
unibrow::Predicate<IdentifierPart, 128> kIsIdentifierPart;
|
||||
unibrow::Predicate<unibrow::LineTerminator, 128> kIsLineTerminator;
|
||||
unibrow::Predicate<unibrow::WhiteSpace, 128> kIsWhiteSpace;
|
||||
StaticResource<Utf8Decoder> utf8_decoder_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UnicodeCache);
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LiteralBuffer - Collector of chars of literals.
|
||||
|
||||
class LiteralBuffer {
|
||||
public:
|
||||
LiteralBuffer() : is_ascii_(true), position_(0), backing_store_() { }
|
||||
|
||||
~LiteralBuffer() {
|
||||
if (backing_store_.length() > 0) {
|
||||
backing_store_.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
INLINE(void AddChar(uint32_t code_unit)) {
|
||||
if (position_ >= backing_store_.length()) ExpandBuffer();
|
||||
if (is_ascii_) {
|
||||
if (code_unit < kMaxAsciiCharCodeU) {
|
||||
backing_store_[position_] = static_cast<byte>(code_unit);
|
||||
position_ += kASCIISize;
|
||||
return;
|
||||
}
|
||||
ConvertToUtf16();
|
||||
}
|
||||
ASSERT(code_unit < 0x10000u);
|
||||
*reinterpret_cast<uc16*>(&backing_store_[position_]) = code_unit;
|
||||
position_ += kUC16Size;
|
||||
}
|
||||
|
||||
bool is_ascii() { return is_ascii_; }
|
||||
|
||||
Vector<const uc16> utf16_literal() {
|
||||
ASSERT(!is_ascii_);
|
||||
ASSERT((position_ & 0x1) == 0);
|
||||
return Vector<const uc16>(
|
||||
reinterpret_cast<const uc16*>(backing_store_.start()),
|
||||
position_ >> 1);
|
||||
}
|
||||
|
||||
Vector<const char> ascii_literal() {
|
||||
ASSERT(is_ascii_);
|
||||
return Vector<const char>(
|
||||
reinterpret_cast<const char*>(backing_store_.start()),
|
||||
position_);
|
||||
}
|
||||
|
||||
int length() {
|
||||
return is_ascii_ ? position_ : (position_ >> 1);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
position_ = 0;
|
||||
is_ascii_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
static const int kInitialCapacity = 16;
|
||||
static const int kGrowthFactory = 4;
|
||||
static const int kMinConversionSlack = 256;
|
||||
static const int kMaxGrowth = 1 * MB;
|
||||
inline int NewCapacity(int min_capacity) {
|
||||
int capacity = Max(min_capacity, backing_store_.length());
|
||||
int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth);
|
||||
return new_capacity;
|
||||
}
|
||||
|
||||
void ExpandBuffer() {
|
||||
Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity));
|
||||
memcpy(new_store.start(), backing_store_.start(), position_);
|
||||
backing_store_.Dispose();
|
||||
backing_store_ = new_store;
|
||||
}
|
||||
|
||||
void ConvertToUtf16() {
|
||||
ASSERT(is_ascii_);
|
||||
Vector<byte> new_store;
|
||||
int new_content_size = position_ * kUC16Size;
|
||||
if (new_content_size >= backing_store_.length()) {
|
||||
// Ensure room for all currently read code units as UC16 as well
|
||||
// as the code unit about to be stored.
|
||||
new_store = Vector<byte>::New(NewCapacity(new_content_size));
|
||||
} else {
|
||||
new_store = backing_store_;
|
||||
}
|
||||
char* src = reinterpret_cast<char*>(backing_store_.start());
|
||||
uc16* dst = reinterpret_cast<uc16*>(new_store.start());
|
||||
for (int i = position_ - 1; i >= 0; i--) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
if (new_store.start() != backing_store_.start()) {
|
||||
backing_store_.Dispose();
|
||||
backing_store_ = new_store;
|
||||
}
|
||||
position_ = new_content_size;
|
||||
is_ascii_ = false;
|
||||
}
|
||||
|
||||
bool is_ascii_;
|
||||
int position_;
|
||||
Vector<byte> backing_store_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LiteralBuffer);
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// JavaScript Scanner.
|
||||
|
||||
class Scanner {
|
||||
public:
|
||||
// Scoped helper for literal recording. Automatically drops the literal
|
||||
// if aborting the scanning before it's complete.
|
||||
class LiteralScope {
|
||||
public:
|
||||
explicit LiteralScope(Scanner* self)
|
||||
: scanner_(self), complete_(false) {
|
||||
scanner_->StartLiteral();
|
||||
}
|
||||
~LiteralScope() {
|
||||
if (!complete_) scanner_->DropLiteral();
|
||||
}
|
||||
void Complete() {
|
||||
scanner_->TerminateLiteral();
|
||||
complete_ = true;
|
||||
}
|
||||
|
||||
private:
|
||||
Scanner* scanner_;
|
||||
bool complete_;
|
||||
};
|
||||
|
||||
// Representation of an interval of source positions.
|
||||
struct Location {
|
||||
Location(int b, int e) : beg_pos(b), end_pos(e) { }
|
||||
Location() : beg_pos(0), end_pos(0) { }
|
||||
|
||||
bool IsValid() const {
|
||||
return beg_pos >= 0 && end_pos >= beg_pos;
|
||||
}
|
||||
|
||||
static Location invalid() { return Location(-1, -1); }
|
||||
|
||||
int beg_pos;
|
||||
int end_pos;
|
||||
};
|
||||
|
||||
// -1 is outside of the range of any real source code.
|
||||
static const int kNoOctalLocation = -1;
|
||||
|
||||
typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
|
||||
|
||||
explicit Scanner(UnicodeCache* scanner_contants);
|
||||
|
||||
void Initialize(Utf16CharacterStream* source);
|
||||
|
||||
// Returns the next token and advances input.
|
||||
Token::Value Next();
|
||||
// Returns the current token again.
|
||||
Token::Value current_token() { return current_.token; }
|
||||
// Returns the location information for the current token
|
||||
// (the token last returned by Next()).
|
||||
Location location() const { return current_.location; }
|
||||
// Returns the literal string, if any, for the current token (the
|
||||
// token last returned by Next()). The string is 0-terminated.
|
||||
// Literal strings are collected for identifiers, strings, and
|
||||
// numbers.
|
||||
// These functions only give the correct result if the literal
|
||||
// was scanned between calls to StartLiteral() and TerminateLiteral().
|
||||
Vector<const char> literal_ascii_string() {
|
||||
ASSERT_NOT_NULL(current_.literal_chars);
|
||||
return current_.literal_chars->ascii_literal();
|
||||
}
|
||||
Vector<const uc16> literal_utf16_string() {
|
||||
ASSERT_NOT_NULL(current_.literal_chars);
|
||||
return current_.literal_chars->utf16_literal();
|
||||
}
|
||||
bool is_literal_ascii() {
|
||||
ASSERT_NOT_NULL(current_.literal_chars);
|
||||
return current_.literal_chars->is_ascii();
|
||||
}
|
||||
int literal_length() const {
|
||||
ASSERT_NOT_NULL(current_.literal_chars);
|
||||
return current_.literal_chars->length();
|
||||
}
|
||||
|
||||
bool literal_contains_escapes() const {
|
||||
Location location = current_.location;
|
||||
int source_length = (location.end_pos - location.beg_pos);
|
||||
if (current_.token == Token::STRING) {
|
||||
// Subtract delimiters.
|
||||
source_length -= 2;
|
||||
}
|
||||
return current_.literal_chars->length() != source_length;
|
||||
}
|
||||
|
||||
// Similar functions for the upcoming token.
|
||||
|
||||
// One token look-ahead (past the token returned by Next()).
|
||||
Token::Value peek() const { return next_.token; }
|
||||
|
||||
Location peek_location() const { return next_.location; }
|
||||
|
||||
// Returns the literal string for the next token (the token that
|
||||
// would be returned if Next() were called).
|
||||
Vector<const char> next_literal_ascii_string() {
|
||||
ASSERT_NOT_NULL(next_.literal_chars);
|
||||
return next_.literal_chars->ascii_literal();
|
||||
}
|
||||
Vector<const uc16> next_literal_utf16_string() {
|
||||
ASSERT_NOT_NULL(next_.literal_chars);
|
||||
return next_.literal_chars->utf16_literal();
|
||||
}
|
||||
bool is_next_literal_ascii() {
|
||||
ASSERT_NOT_NULL(next_.literal_chars);
|
||||
return next_.literal_chars->is_ascii();
|
||||
}
|
||||
int next_literal_length() const {
|
||||
ASSERT_NOT_NULL(next_.literal_chars);
|
||||
return next_.literal_chars->length();
|
||||
}
|
||||
|
||||
UnicodeCache* unicode_cache() { return unicode_cache_; }
|
||||
|
||||
static const int kCharacterLookaheadBufferSize = 1;
|
||||
|
||||
// Scans octal escape sequence. Also accepts "\0" decimal escape sequence.
|
||||
uc32 ScanOctalEscape(uc32 c, int length);
|
||||
|
||||
// Returns the location of the last seen octal literal.
|
||||
Location octal_position() const { return octal_pos_; }
|
||||
void clear_octal_position() { octal_pos_ = Location::invalid(); }
|
||||
|
||||
// Seek forward to the given position. This operation does not
|
||||
// work in general, for instance when there are pushed back
|
||||
// characters, but works for seeking forward until simple delimiter
|
||||
// tokens, which is what it is used for.
|
||||
void SeekForward(int pos);
|
||||
|
||||
bool HarmonyScoping() const {
|
||||
return harmony_scoping_;
|
||||
}
|
||||
void SetHarmonyScoping(bool scoping) {
|
||||
harmony_scoping_ = scoping;
|
||||
}
|
||||
bool HarmonyModules() const {
|
||||
return harmony_modules_;
|
||||
}
|
||||
void SetHarmonyModules(bool modules) {
|
||||
harmony_modules_ = modules;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if there was a line terminator before the peek'ed token,
|
||||
// possibly inside a multi-line comment.
|
||||
bool HasAnyLineTerminatorBeforeNext() const {
|
||||
return has_line_terminator_before_next_ ||
|
||||
has_multiline_comment_before_next_;
|
||||
}
|
||||
|
||||
// Scans the input as a regular expression pattern, previous
|
||||
// character(s) must be /(=). Returns true if a pattern is scanned.
|
||||
bool ScanRegExpPattern(bool seen_equal);
|
||||
// Returns true if regexp flags are scanned (always since flags can
|
||||
// be empty).
|
||||
bool ScanRegExpFlags();
|
||||
|
||||
// Tells whether the buffer contains an identifier (no escapes).
|
||||
// Used for checking if a property name is an identifier.
|
||||
static bool IsIdentifier(unibrow::CharacterStream* buffer);
|
||||
|
||||
private:
|
||||
// The current and look-ahead token.
|
||||
struct TokenDesc {
|
||||
Token::Value token;
|
||||
Location location;
|
||||
LiteralBuffer* literal_chars;
|
||||
};
|
||||
|
||||
// Call this after setting source_ to the input.
|
||||
void Init() {
|
||||
// Set c0_ (one character ahead)
|
||||
STATIC_ASSERT(kCharacterLookaheadBufferSize == 1);
|
||||
Advance();
|
||||
// Initialize current_ to not refer to a literal.
|
||||
current_.literal_chars = NULL;
|
||||
}
|
||||
|
||||
// Literal buffer support
|
||||
inline void StartLiteral() {
|
||||
LiteralBuffer* free_buffer = (current_.literal_chars == &literal_buffer1_) ?
|
||||
&literal_buffer2_ : &literal_buffer1_;
|
||||
free_buffer->Reset();
|
||||
next_.literal_chars = free_buffer;
|
||||
}
|
||||
|
||||
INLINE(void AddLiteralChar(uc32 c)) {
|
||||
ASSERT_NOT_NULL(next_.literal_chars);
|
||||
next_.literal_chars->AddChar(c);
|
||||
}
|
||||
|
||||
// Complete scanning of a literal.
|
||||
inline void TerminateLiteral() {
|
||||
// Does nothing in the current implementation.
|
||||
}
|
||||
|
||||
// Stops scanning of a literal and drop the collected characters,
|
||||
// e.g., due to an encountered error.
|
||||
inline void DropLiteral() {
|
||||
next_.literal_chars = NULL;
|
||||
}
|
||||
|
||||
inline void AddLiteralCharAdvance() {
|
||||
AddLiteralChar(c0_);
|
||||
Advance();
|
||||
}
|
||||
|
||||
// Low-level scanning support.
|
||||
void Advance() { c0_ = source_->Advance(); }
|
||||
void PushBack(uc32 ch) {
|
||||
source_->PushBack(c0_);
|
||||
c0_ = ch;
|
||||
}
|
||||
|
||||
inline Token::Value Select(Token::Value tok) {
|
||||
Advance();
|
||||
return tok;
|
||||
}
|
||||
|
||||
inline Token::Value Select(uc32 next, Token::Value then, Token::Value else_) {
|
||||
Advance();
|
||||
if (c0_ == next) {
|
||||
Advance();
|
||||
return then;
|
||||
} else {
|
||||
return else_;
|
||||
}
|
||||
}
|
||||
|
||||
uc32 ScanHexNumber(int expected_length);
|
||||
|
||||
// Scans a single JavaScript token.
|
||||
void Scan();
|
||||
|
||||
bool SkipWhiteSpace();
|
||||
Token::Value SkipSingleLineComment();
|
||||
Token::Value SkipMultiLineComment();
|
||||
// Scans a possible HTML comment -- begins with '<!'.
|
||||
Token::Value ScanHtmlComment();
|
||||
|
||||
void ScanDecimalDigits();
|
||||
Token::Value ScanNumber(bool seen_period);
|
||||
Token::Value ScanIdentifierOrKeyword();
|
||||
Token::Value ScanIdentifierSuffix(LiteralScope* literal);
|
||||
|
||||
Token::Value ScanString();
|
||||
|
||||
// Scans an escape-sequence which is part of a string and adds the
|
||||
// decoded character to the current literal. Returns true if a pattern
|
||||
// is scanned.
|
||||
bool ScanEscape();
|
||||
// Decodes a Unicode escape-sequence which is part of an identifier.
|
||||
// If the escape sequence cannot be decoded the result is kBadChar.
|
||||
uc32 ScanIdentifierUnicodeEscape();
|
||||
// Scans a Unicode escape-sequence and adds its characters,
|
||||
// uninterpreted, to the current literal. Used for parsing RegExp
|
||||
// flags.
|
||||
bool ScanLiteralUnicodeEscape();
|
||||
|
||||
// Return the current source position.
|
||||
int source_pos() {
|
||||
return source_->pos() - kCharacterLookaheadBufferSize;
|
||||
}
|
||||
|
||||
UnicodeCache* unicode_cache_;
|
||||
|
||||
// Buffers collecting literal strings, numbers, etc.
|
||||
LiteralBuffer literal_buffer1_;
|
||||
LiteralBuffer literal_buffer2_;
|
||||
|
||||
TokenDesc current_; // desc for current token (as returned by Next())
|
||||
TokenDesc next_; // desc for next token (one token look-ahead)
|
||||
|
||||
// Input stream. Must be initialized to an Utf16CharacterStream.
|
||||
Utf16CharacterStream* source_;
|
||||
|
||||
|
||||
// Start position of the octal literal last scanned.
|
||||
Location octal_pos_;
|
||||
|
||||
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
|
||||
uc32 c0_;
|
||||
|
||||
// Whether there is a line terminator whitespace character after
|
||||
// the current token, and before the next. Does not count newlines
|
||||
// inside multiline comments.
|
||||
bool has_line_terminator_before_next_;
|
||||
// Whether there is a multi-line comment that contains a
|
||||
// line-terminator after the current token, and before the next.
|
||||
bool has_multiline_comment_before_next_;
|
||||
// Whether we scan 'let' as a keyword for harmony block-scoped let bindings.
|
||||
bool harmony_scoping_;
|
||||
// Whether we scan 'module', 'import', 'export' as keywords.
|
||||
bool harmony_modules_;
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_SCANNER_H_
|
||||
71
test/fixtures/cpp/utils.h
vendored
71
test/fixtures/cpp/utils.h
vendored
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QWebFrame>
|
||||
#include <QFile>
|
||||
|
||||
#include "csconverter.h"
|
||||
#include "encoding.h"
|
||||
|
||||
class QTemporaryFile;
|
||||
/**
|
||||
* Aggregate common utility functions.
|
||||
* Functions are static methods.
|
||||
* It's important to notice that, at the moment, this class can't be instantiated by design.
|
||||
*/
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
static void showUsage();
|
||||
static void messageHandler(QtMsgType type, const char *msg);
|
||||
static bool exceptionHandler(const char* dump_path, const char* minidump_id, void* context, bool succeeded);
|
||||
static QVariant coffee2js(const QString &script);
|
||||
static bool injectJsInFrame(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
||||
static bool injectJsInFrame(const QString &jsFilePath, const Encoding &jsFileEnc, const QString &libraryPath, QWebFrame *targetFrame, const bool startingScript = false);
|
||||
static QString readResourceFileUtf8(const QString &resourceFilePath);
|
||||
|
||||
static bool loadJSForDebug(const QString &jsFilePath, const Encoding &jsFileEnc, const QString &libraryPath, QWebFrame *targetFrame, const bool autorun = false);
|
||||
static bool loadJSForDebug(const QString &jsFilePath, const QString &libraryPath, QWebFrame *targetFrame, const bool autorun = false);
|
||||
static void cleanupFromDebug();
|
||||
|
||||
private:
|
||||
static QString findScript(const QString &jsFilePath, const QString& libraryPath);
|
||||
static QString jsFromScriptFile(const QString& scriptPath, const Encoding& enc);
|
||||
Utils(); //< This class shouldn't be instantiated
|
||||
|
||||
static QTemporaryFile* m_tempHarness; //< We want to make sure to clean up after ourselves
|
||||
static QTemporaryFile* m_tempWrapper;
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
||||
288
test/fixtures/cpp/v8.cc
vendored
288
test/fixtures/cpp/v8.cc
vendored
@@ -1,288 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "v8.h"
|
||||
|
||||
#include "assembler.h"
|
||||
#include "isolate.h"
|
||||
#include "elements.h"
|
||||
#include "bootstrapper.h"
|
||||
#include "debug.h"
|
||||
#include "deoptimizer.h"
|
||||
#include "frames.h"
|
||||
#include "heap-profiler.h"
|
||||
#include "hydrogen.h"
|
||||
#include "lithium-allocator.h"
|
||||
#include "log.h"
|
||||
#include "once.h"
|
||||
#include "platform.h"
|
||||
#include "runtime-profiler.h"
|
||||
#include "serialize.h"
|
||||
#include "store-buffer.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
V8_DECLARE_ONCE(init_once);
|
||||
|
||||
bool V8::is_running_ = false;
|
||||
bool V8::has_been_set_up_ = false;
|
||||
bool V8::has_been_disposed_ = false;
|
||||
bool V8::has_fatal_error_ = false;
|
||||
bool V8::use_crankshaft_ = true;
|
||||
List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
|
||||
|
||||
static LazyMutex entropy_mutex = LAZY_MUTEX_INITIALIZER;
|
||||
|
||||
static EntropySource entropy_source;
|
||||
|
||||
|
||||
bool V8::Initialize(Deserializer* des) {
|
||||
FlagList::EnforceFlagImplications();
|
||||
|
||||
InitializeOncePerProcess();
|
||||
|
||||
// The current thread may not yet had entered an isolate to run.
|
||||
// Note the Isolate::Current() may be non-null because for various
|
||||
// initialization purposes an initializing thread may be assigned an isolate
|
||||
// but not actually enter it.
|
||||
if (i::Isolate::CurrentPerIsolateThreadData() == NULL) {
|
||||
i::Isolate::EnterDefaultIsolate();
|
||||
}
|
||||
|
||||
ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
|
||||
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
|
||||
i::ThreadId::Current()));
|
||||
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
|
||||
i::Isolate::Current());
|
||||
|
||||
if (IsDead()) return false;
|
||||
|
||||
Isolate* isolate = Isolate::Current();
|
||||
if (isolate->IsInitialized()) return true;
|
||||
|
||||
is_running_ = true;
|
||||
has_been_set_up_ = true;
|
||||
has_fatal_error_ = false;
|
||||
has_been_disposed_ = false;
|
||||
|
||||
return isolate->Init(des);
|
||||
}
|
||||
|
||||
|
||||
void V8::SetFatalError() {
|
||||
is_running_ = false;
|
||||
has_fatal_error_ = true;
|
||||
}
|
||||
|
||||
|
||||
void V8::TearDown() {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ASSERT(isolate->IsDefaultIsolate());
|
||||
|
||||
if (!has_been_set_up_ || has_been_disposed_) return;
|
||||
|
||||
ElementsAccessor::TearDown();
|
||||
LOperand::TearDownCaches();
|
||||
RegisteredExtension::UnregisterAll();
|
||||
|
||||
isolate->TearDown();
|
||||
delete isolate;
|
||||
|
||||
is_running_ = false;
|
||||
has_been_disposed_ = true;
|
||||
|
||||
delete call_completed_callbacks_;
|
||||
call_completed_callbacks_ = NULL;
|
||||
|
||||
OS::TearDown();
|
||||
}
|
||||
|
||||
|
||||
static void seed_random(uint32_t* state) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (FLAG_random_seed != 0) {
|
||||
state[i] = FLAG_random_seed;
|
||||
} else if (entropy_source != NULL) {
|
||||
uint32_t val;
|
||||
ScopedLock lock(entropy_mutex.Pointer());
|
||||
entropy_source(reinterpret_cast<unsigned char*>(&val), sizeof(uint32_t));
|
||||
state[i] = val;
|
||||
} else {
|
||||
state[i] = random();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Random number generator using George Marsaglia's MWC algorithm.
|
||||
static uint32_t random_base(uint32_t* state) {
|
||||
// Initialize seed using the system random().
|
||||
// No non-zero seed will ever become zero again.
|
||||
if (state[0] == 0) seed_random(state);
|
||||
|
||||
// Mix the bits. Never replaces state[i] with 0 if it is nonzero.
|
||||
state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16);
|
||||
state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16);
|
||||
|
||||
return (state[0] << 14) + (state[1] & 0x3FFFF);
|
||||
}
|
||||
|
||||
|
||||
void V8::SetEntropySource(EntropySource source) {
|
||||
entropy_source = source;
|
||||
}
|
||||
|
||||
|
||||
void V8::SetReturnAddressLocationResolver(
|
||||
ReturnAddressLocationResolver resolver) {
|
||||
StackFrame::SetReturnAddressLocationResolver(resolver);
|
||||
}
|
||||
|
||||
|
||||
// Used by JavaScript APIs
|
||||
uint32_t V8::Random(Context* context) {
|
||||
ASSERT(context->IsGlobalContext());
|
||||
ByteArray* seed = context->random_seed();
|
||||
return random_base(reinterpret_cast<uint32_t*>(seed->GetDataStartAddress()));
|
||||
}
|
||||
|
||||
|
||||
// Used internally by the JIT and memory allocator for security
|
||||
// purposes. So, we keep a different state to prevent informations
|
||||
// leaks that could be used in an exploit.
|
||||
uint32_t V8::RandomPrivate(Isolate* isolate) {
|
||||
ASSERT(isolate == Isolate::Current());
|
||||
return random_base(isolate->private_random_seed());
|
||||
}
|
||||
|
||||
|
||||
bool V8::IdleNotification(int hint) {
|
||||
// Returning true tells the caller that there is no need to call
|
||||
// IdleNotification again.
|
||||
if (!FLAG_use_idle_notification) return true;
|
||||
|
||||
// Tell the heap that it may want to adjust.
|
||||
return HEAP->IdleNotification(hint);
|
||||
}
|
||||
|
||||
|
||||
void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
|
||||
if (call_completed_callbacks_ == NULL) { // Lazy init.
|
||||
call_completed_callbacks_ = new List<CallCompletedCallback>();
|
||||
}
|
||||
for (int i = 0; i < call_completed_callbacks_->length(); i++) {
|
||||
if (callback == call_completed_callbacks_->at(i)) return;
|
||||
}
|
||||
call_completed_callbacks_->Add(callback);
|
||||
}
|
||||
|
||||
|
||||
void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
|
||||
if (call_completed_callbacks_ == NULL) return;
|
||||
for (int i = 0; i < call_completed_callbacks_->length(); i++) {
|
||||
if (callback == call_completed_callbacks_->at(i)) {
|
||||
call_completed_callbacks_->Remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void V8::FireCallCompletedCallback(Isolate* isolate) {
|
||||
if (call_completed_callbacks_ == NULL) return;
|
||||
HandleScopeImplementer* handle_scope_implementer =
|
||||
isolate->handle_scope_implementer();
|
||||
if (!handle_scope_implementer->CallDepthIsZero()) return;
|
||||
// Fire callbacks. Increase call depth to prevent recursive callbacks.
|
||||
handle_scope_implementer->IncrementCallDepth();
|
||||
for (int i = 0; i < call_completed_callbacks_->length(); i++) {
|
||||
call_completed_callbacks_->at(i)();
|
||||
}
|
||||
handle_scope_implementer->DecrementCallDepth();
|
||||
}
|
||||
|
||||
|
||||
// Use a union type to avoid type-aliasing optimizations in GCC.
|
||||
typedef union {
|
||||
double double_value;
|
||||
uint64_t uint64_t_value;
|
||||
} double_int_union;
|
||||
|
||||
|
||||
Object* V8::FillHeapNumberWithRandom(Object* heap_number,
|
||||
Context* context) {
|
||||
double_int_union r;
|
||||
uint64_t random_bits = Random(context);
|
||||
// Convert 32 random bits to 0.(32 random bits) in a double
|
||||
// by computing:
|
||||
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
|
||||
static const double binary_million = 1048576.0;
|
||||
r.double_value = binary_million;
|
||||
r.uint64_t_value |= random_bits;
|
||||
r.double_value -= binary_million;
|
||||
|
||||
HeapNumber::cast(heap_number)->set_value(r.double_value);
|
||||
return heap_number;
|
||||
}
|
||||
|
||||
void V8::InitializeOncePerProcessImpl() {
|
||||
OS::SetUp();
|
||||
|
||||
use_crankshaft_ = FLAG_crankshaft;
|
||||
|
||||
if (Serializer::enabled()) {
|
||||
use_crankshaft_ = false;
|
||||
}
|
||||
|
||||
CPU::SetUp();
|
||||
if (!CPU::SupportsCrankshaft()) {
|
||||
use_crankshaft_ = false;
|
||||
}
|
||||
|
||||
OS::PostSetUp();
|
||||
|
||||
RuntimeProfiler::GlobalSetUp();
|
||||
|
||||
ElementsAccessor::InitializeOncePerProcess();
|
||||
|
||||
if (FLAG_stress_compaction) {
|
||||
FLAG_force_marking_deque_overflows = true;
|
||||
FLAG_gc_global = true;
|
||||
FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
|
||||
}
|
||||
|
||||
LOperand::SetUpCaches();
|
||||
SetUpJSCallerSavedCodeData();
|
||||
SamplerRegistry::SetUp();
|
||||
ExternalReference::SetUp();
|
||||
}
|
||||
|
||||
void V8::InitializeOncePerProcess() {
|
||||
CallOnce(&init_once, &InitializeOncePerProcessImpl);
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
152
test/fixtures/cpp/v8.h
vendored
152
test/fixtures/cpp/v8.h
vendored
@@ -1,152 +0,0 @@
|
||||
// Copyright 2011 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// Top include for all V8 .cc files.
|
||||
//
|
||||
|
||||
#ifndef V8_V8_H_
|
||||
#define V8_V8_H_
|
||||
|
||||
#if defined(GOOGLE3)
|
||||
// Google3 special flag handling.
|
||||
#if defined(DEBUG) && defined(NDEBUG)
|
||||
// V8 only uses DEBUG and whenever it is set we are building a debug
|
||||
// version of V8. We do not use NDEBUG and simply undef it here for
|
||||
// consistency.
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
#endif // defined(GOOGLE3)
|
||||
|
||||
// V8 only uses DEBUG, but included external files
|
||||
// may use NDEBUG - make sure they are consistent.
|
||||
#if defined(DEBUG) && defined(NDEBUG)
|
||||
#error both DEBUG and NDEBUG are set
|
||||
#endif
|
||||
|
||||
// Basic includes
|
||||
#include "../include/v8.h"
|
||||
#include "v8globals.h"
|
||||
#include "v8checks.h"
|
||||
#include "allocation.h"
|
||||
#include "v8utils.h"
|
||||
#include "flags.h"
|
||||
|
||||
// Objects & heap
|
||||
#include "objects-inl.h"
|
||||
#include "spaces-inl.h"
|
||||
#include "heap-inl.h"
|
||||
#include "incremental-marking-inl.h"
|
||||
#include "mark-compact-inl.h"
|
||||
#include "log-inl.h"
|
||||
#include "cpu-profiler-inl.h"
|
||||
#include "handles-inl.h"
|
||||
#include "zone-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class Deserializer;
|
||||
|
||||
class V8 : public AllStatic {
|
||||
public:
|
||||
// Global actions.
|
||||
|
||||
// If Initialize is called with des == NULL, the initial state is
|
||||
// created from scratch. If a non-null Deserializer is given, the
|
||||
// initial state is created by reading the deserialized data into an
|
||||
// empty heap.
|
||||
static bool Initialize(Deserializer* des);
|
||||
static void TearDown();
|
||||
static bool IsRunning() { return is_running_; }
|
||||
static bool UseCrankshaft() { return use_crankshaft_; }
|
||||
// To be dead you have to have lived
|
||||
// TODO(isolates): move IsDead to Isolate.
|
||||
static bool IsDead() { return has_fatal_error_ || has_been_disposed_; }
|
||||
static void SetFatalError();
|
||||
|
||||
// Report process out of memory. Implementation found in api.cc.
|
||||
static void FatalProcessOutOfMemory(const char* location,
|
||||
bool take_snapshot = false);
|
||||
|
||||
// Allows an entropy source to be provided for use in random number
|
||||
// generation.
|
||||
static void SetEntropySource(EntropySource source);
|
||||
// Support for return-address rewriting profilers.
|
||||
static void SetReturnAddressLocationResolver(
|
||||
ReturnAddressLocationResolver resolver);
|
||||
// Random number generation support. Not cryptographically safe.
|
||||
static uint32_t Random(Context* context);
|
||||
// We use random numbers internally in memory allocation and in the
|
||||
// compilers for security. In order to prevent information leaks we
|
||||
// use a separate random state for internal random number
|
||||
// generation.
|
||||
static uint32_t RandomPrivate(Isolate* isolate);
|
||||
static Object* FillHeapNumberWithRandom(Object* heap_number,
|
||||
Context* context);
|
||||
|
||||
// Idle notification directly from the API.
|
||||
static bool IdleNotification(int hint);
|
||||
|
||||
static void AddCallCompletedCallback(CallCompletedCallback callback);
|
||||
static void RemoveCallCompletedCallback(CallCompletedCallback callback);
|
||||
static void FireCallCompletedCallback(Isolate* isolate);
|
||||
|
||||
private:
|
||||
static void InitializeOncePerProcessImpl();
|
||||
static void InitializeOncePerProcess();
|
||||
|
||||
// True if engine is currently running
|
||||
static bool is_running_;
|
||||
// True if V8 has ever been run
|
||||
static bool has_been_set_up_;
|
||||
// True if error has been signaled for current engine
|
||||
// (reset to false if engine is restarted)
|
||||
static bool has_fatal_error_;
|
||||
// True if engine has been shut down
|
||||
// (reset if engine is restarted)
|
||||
static bool has_been_disposed_;
|
||||
// True if we are using the crankshaft optimizing compiler.
|
||||
static bool use_crankshaft_;
|
||||
// List of callbacks when a Call completes.
|
||||
static List<CallCompletedCallback>* call_completed_callbacks_;
|
||||
};
|
||||
|
||||
|
||||
// JavaScript defines two kinds of 'nil'.
|
||||
enum NilValue { kNullValue, kUndefinedValue };
|
||||
|
||||
|
||||
// JavaScript defines two kinds of equality.
|
||||
enum EqualityKind { kStrictEquality, kNonStrictEquality };
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
namespace i = v8::internal;
|
||||
|
||||
#endif // V8_V8_H_
|
||||
15
test/fixtures/dart/point.dart
vendored
15
test/fixtures/dart/point.dart
vendored
@@ -1,15 +0,0 @@
|
||||
class Point {
|
||||
Point(this.x, this.y);
|
||||
distanceTo(Point other) {
|
||||
var dx = x - other.x;
|
||||
var dy = y - other.y;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
var x, y;
|
||||
}
|
||||
|
||||
main() {
|
||||
Point p = new Point(2, 3);
|
||||
Point q = new Point(3, 4);
|
||||
print('distance from p to q = ${p.distanceTo(q)}');
|
||||
}
|
||||
14
test/fixtures/delphi/program.dpr
vendored
14
test/fixtures/delphi/program.dpr
vendored
@@ -1,14 +0,0 @@
|
||||
program gmail;
|
||||
|
||||
uses
|
||||
Forms,
|
||||
Unit2 in 'Unit2.pas' {Form2};
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
Application.Initialize;
|
||||
Application.MainFormOnTaskbar := True;
|
||||
Application.CreateForm(TForm2, Form2);
|
||||
Application.Run;
|
||||
end.
|
||||
@@ -1,4 +0,0 @@
|
||||
diff --git a/lib/linguist.rb b/lib/linguist.rb
|
||||
index d472341..8ad9ffb 100644
|
||||
--- a/lib/linguist.rb
|
||||
+++ b/lib/linguist.rb
|
||||
1
test/fixtures/emacs/dude.el
vendored
1
test/fixtures/emacs/dude.el
vendored
@@ -1 +0,0 @@
|
||||
(print "Dude!")
|
||||
63
test/fixtures/gas/hello.s
vendored
63
test/fixtures/gas/hello.s
vendored
@@ -1,63 +0,0 @@
|
||||
.cstring
|
||||
LC0:
|
||||
.ascii "Hello World\0"
|
||||
.text
|
||||
.globl _main
|
||||
_main:
|
||||
LFB3:
|
||||
pushq %rbp
|
||||
LCFI0:
|
||||
movq %rsp, %rbp
|
||||
LCFI1:
|
||||
leaq LC0(%rip), %rdi
|
||||
call _puts
|
||||
movl $0, %eax
|
||||
leave
|
||||
ret
|
||||
LFE3:
|
||||
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
|
||||
EH_frame1:
|
||||
.set L$set$0,LECIE1-LSCIE1
|
||||
.long L$set$0
|
||||
LSCIE1:
|
||||
.long 0x0
|
||||
.byte 0x1
|
||||
.ascii "zR\0"
|
||||
.byte 0x1
|
||||
.byte 0x78
|
||||
.byte 0x10
|
||||
.byte 0x1
|
||||
.byte 0x10
|
||||
.byte 0xc
|
||||
.byte 0x7
|
||||
.byte 0x8
|
||||
.byte 0x90
|
||||
.byte 0x1
|
||||
.align 3
|
||||
LECIE1:
|
||||
.globl _main.eh
|
||||
_main.eh:
|
||||
LSFDE1:
|
||||
.set L$set$1,LEFDE1-LASFDE1
|
||||
.long L$set$1
|
||||
LASFDE1:
|
||||
.long LASFDE1-EH_frame1
|
||||
.quad LFB3-.
|
||||
.set L$set$2,LFE3-LFB3
|
||||
.quad L$set$2
|
||||
.byte 0x0
|
||||
.byte 0x4
|
||||
.set L$set$3,LCFI0-LFB3
|
||||
.long L$set$3
|
||||
.byte 0xe
|
||||
.byte 0x10
|
||||
.byte 0x86
|
||||
.byte 0x2
|
||||
.byte 0x4
|
||||
.set L$set$4,LCFI1-LCFI0
|
||||
.long L$set$4
|
||||
.byte 0xd
|
||||
.byte 0x6
|
||||
.align 3
|
||||
LEFDE1:
|
||||
.subsections_via_symbols
|
||||
7
test/fixtures/gosu/Hello.gst
vendored
7
test/fixtures/gosu/Hello.gst
vendored
@@ -1,7 +0,0 @@
|
||||
<%!-- defined in Hello.gst --%>
|
||||
|
||||
<%@ params( users : Collection <User> ) %>
|
||||
|
||||
<% for( user in users ) { %>
|
||||
|
||||
${user.LastName}, ${user.FirstName}, ${user.Department} <% } %>
|
||||
9
test/fixtures/gosu/Hello.gsx
vendored
9
test/fixtures/gosu/Hello.gsx
vendored
@@ -1,9 +0,0 @@
|
||||
package example
|
||||
|
||||
enhancement Hello : String {
|
||||
|
||||
function toPerson() : Person {
|
||||
var vals = this.split(",")
|
||||
return new Person( vals[0], vals[1] as int, Relationship.valueOf( vals[2] ) ) )
|
||||
}
|
||||
}
|
||||
106
test/fixtures/gosu/Person.gs
vendored
106
test/fixtures/gosu/Person.gs
vendored
@@ -1,106 +0,0 @@
|
||||
package example
|
||||
|
||||
uses java.util.*
|
||||
|
||||
uses java.io.File
|
||||
|
||||
class Person extends Contact implements IEmailable {
|
||||
|
||||
var _name : String
|
||||
var _age : Integer as Age
|
||||
var _relationship : Relationship as readonly RelationshipOfPerson
|
||||
|
||||
delegate _emailHelper represents IEmailable
|
||||
|
||||
enum Relationship {
|
||||
FRIEND,
|
||||
FAMILY,
|
||||
BUSINESS_CONTACT
|
||||
}
|
||||
|
||||
// Map of names to people
|
||||
static var ALL_PEOPLE = new HashMap<String, Person>()
|
||||
|
||||
/* Constructs a new Person */
|
||||
construct( name : String, age : Integer, relationship : Relationship ) {
|
||||
_name = name
|
||||
_age = age
|
||||
_relationship = relationship
|
||||
_emailHelper = new EmailHelper( this )
|
||||
}
|
||||
|
||||
property get Name():String{
|
||||
return _name
|
||||
}
|
||||
|
||||
property set Name(name : String){
|
||||
_name = name
|
||||
}
|
||||
|
||||
/* Implement IEmailable#getEmailName() */
|
||||
override function getEmailName():String{
|
||||
return Name
|
||||
}
|
||||
|
||||
function incrementAge() {
|
||||
_age++
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
function printPersonInfo() {
|
||||
print( "Person { Name : ${Name}, Age : ${Age}, Relationship : ${RelationshipOfPerson} }" )
|
||||
}
|
||||
|
||||
static function addPerson(p : Person){
|
||||
if(ALL_PEOPLE.containsKey(p?.Name)) {
|
||||
throw new IllegalArgumentException( "There is already someone named '${p.Name}'." )
|
||||
}
|
||||
ALL_PEOPLE[p.Name] = p
|
||||
}
|
||||
|
||||
static function addAllPeople( contacts : List<Contact> ) {
|
||||
for( contact in contacts ) {
|
||||
if( contact typeis Person and not ALL_PEOPLE.containsKey( contact.Name )) {
|
||||
addPerson( contact )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function getAllPeopleOlderThanNOrderedByName( age : int ) {
|
||||
var allPeople = ALL_PEOPLE.Values
|
||||
|
||||
return allPeople.where( \ p -> p.Age > age ).orderBy( \ p -> p.Name )
|
||||
}
|
||||
|
||||
static function loadPersonFromDB( id : Integer ) {
|
||||
using( var conn = DBConnectionManager.getConnection(),
|
||||
var stmt = conn.prepareStatement( "SELECT name, age, relationship FROM PEOPLE WHERE ID=?") ){
|
||||
|
||||
stmt.setInt( 0, 0 )
|
||||
var result = stmt.executeQuery()
|
||||
if( result.next() ) {
|
||||
addPerson( new Person( result.getString( "name" ),
|
||||
result.getInt( "age" ),
|
||||
Relationship.valueOf( result.getString( "relationship" ) ) ) )
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Loads in people from a CSV */
|
||||
static function loadFromFile( file : File ) {
|
||||
file.eachLine( \ line -> {
|
||||
if( line.HasContent ) {
|
||||
addPerson( line.toPerson() )
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* Save people to a CSV */
|
||||
static function saveToFile( file : File ) {
|
||||
using( var writer = new FileWriter( file ) ) {
|
||||
print( PersonCSVTemplate.renderToString( ALL_PEOPLE.Values ) )
|
||||
PersonCSVTemplate.render( writer, ALL_PEOPLE.Values )
|
||||
}
|
||||
}
|
||||
}
|
||||
1
test/fixtures/gosu/hello.gsp
vendored
1
test/fixtures/gosu/hello.gsp
vendored
@@ -1 +0,0 @@
|
||||
print("hello")
|
||||
3
test/fixtures/gosu/hello.vark
vendored
3
test/fixtures/gosu/hello.vark
vendored
@@ -1,3 +0,0 @@
|
||||
function hello() {
|
||||
print("hello")
|
||||
}
|
||||
17
test/fixtures/groovy/build.gradle
vendored
17
test/fixtures/groovy/build.gradle
vendored
@@ -1,17 +0,0 @@
|
||||
task echoDirListViaAntBuilder() {
|
||||
description = 'Uses the built-in AntBuilder instance to echo and list files'
|
||||
//Docs: http://ant.apache.org/manual/Types/fileset.html
|
||||
|
||||
//Echo the Gradle project name via the ant echo plugin
|
||||
ant.echo(message: project.name)
|
||||
ant.echo(path)
|
||||
ant.echo("${projectDir}/samples")
|
||||
|
||||
//Gather list of files in a subdirectory
|
||||
ant.fileScanner{
|
||||
fileset(dir:"samples")
|
||||
}.each{
|
||||
//Print each file to screen with the CWD (projectDir) path removed.
|
||||
println it.toString() - "${projectDir}"
|
||||
}
|
||||
}
|
||||
2
test/fixtures/groovy/script.groovy
vendored
2
test/fixtures/groovy/script.groovy
vendored
@@ -1,2 +0,0 @@
|
||||
#!/usr/bin/env groovy
|
||||
println "Groovy!"
|
||||
10
test/fixtures/gsp/bar.gsp
vendored
10
test/fixtures/gsp/bar.gsp
vendored
@@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Testing with SiteMesh and Resources</title>
|
||||
<meta name="layout" content="blankMain"/>
|
||||
<r:require module="style"/>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
16
test/fixtures/gsp/hello-pagedirective.gsp
vendored
16
test/fixtures/gsp/hello-pagedirective.gsp
vendored
@@ -1,16 +0,0 @@
|
||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Using page directive tag</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="center">
|
||||
<a href="#" alt="Download" id="downloadButton">Download</a>
|
||||
</div>
|
||||
<div class="center">
|
||||
<a href="#" alt="Print" id="printButton">Print</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
9
test/fixtures/gsp/hello-resources.gsp
vendored
9
test/fixtures/gsp/hello-resources.gsp
vendored
@@ -1,9 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Testing with Resources</title>
|
||||
<r:require module="style"/>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
9
test/fixtures/gsp/hello-var.gsp
vendored
9
test/fixtures/gsp/hello-var.gsp
vendored
@@ -1,9 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Testing with SiteMesh and ${example}</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
3
test/fixtures/haml/hello.haml
vendored
3
test/fixtures/haml/hello.haml
vendored
@@ -1,3 +0,0 @@
|
||||
%p
|
||||
Hello,
|
||||
World!
|
||||
3
test/fixtures/ini/.gitconfig
vendored
3
test/fixtures/ini/.gitconfig
vendored
@@ -1,3 +0,0 @@
|
||||
[user]
|
||||
name = Josh Peek
|
||||
email = josh@github.com
|
||||
3
test/fixtures/ioke/hello.ik
vendored
3
test/fixtures/ioke/hello.ik
vendored
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env ioke
|
||||
|
||||
"Hello world." println
|
||||
243
test/fixtures/java/HtmlDomParserContext.java
vendored
243
test/fixtures/java/HtmlDomParserContext.java
vendored
@@ -1,243 +0,0 @@
|
||||
/**
|
||||
* (The MIT License)
|
||||
*
|
||||
* Copyright (c) 2008 - 2012:
|
||||
*
|
||||
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
||||
* * {Mike Dalessio}[http://mike.daless.io]
|
||||
* * {Charles Nutter}[http://blog.headius.com]
|
||||
* * {Sergio Arbeo}[http://www.serabe.com]
|
||||
* * {Patrick Mahoney}[http://polycrystal.org]
|
||||
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nokogiri.internals;
|
||||
|
||||
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
||||
import static nokogiri.internals.NokogiriHelpers.isNamespace;
|
||||
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
|
||||
import nokogiri.HtmlDocument;
|
||||
import nokogiri.NokogiriService;
|
||||
import nokogiri.XmlDocument;
|
||||
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.apache.xerces.xni.Augmentations;
|
||||
import org.apache.xerces.xni.QName;
|
||||
import org.apache.xerces.xni.XMLAttributes;
|
||||
import org.apache.xerces.xni.XNIException;
|
||||
import org.apache.xerces.xni.parser.XMLDocumentFilter;
|
||||
import org.apache.xerces.xni.parser.XMLParserConfiguration;
|
||||
import org.cyberneko.html.HTMLConfiguration;
|
||||
import org.cyberneko.html.filters.DefaultFilter;
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Parser for HtmlDocument. This class actually parses HtmlDocument using NekoHtml.
|
||||
*
|
||||
* @author sergio
|
||||
* @author Patrick Mahoney <pat@polycrystal.org>
|
||||
* @author Yoko Harada <yokolet@gmail.com>
|
||||
*/
|
||||
public class HtmlDomParserContext extends XmlDomParserContext {
|
||||
|
||||
public HtmlDomParserContext(Ruby runtime, IRubyObject options) {
|
||||
super(runtime, options);
|
||||
}
|
||||
|
||||
public HtmlDomParserContext(Ruby runtime, IRubyObject encoding, IRubyObject options) {
|
||||
super(runtime, encoding, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initErrorHandler() {
|
||||
if (options.strict) {
|
||||
errorHandler = new NokogiriStrictErrorHandler(options.noError, options.noWarning);
|
||||
} else {
|
||||
errorHandler = new NokogiriNonStrictErrorHandler4NekoHtml(options.noError, options.noWarning);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initParser(Ruby runtime) {
|
||||
XMLParserConfiguration config = new HTMLConfiguration();
|
||||
XMLDocumentFilter removeNSAttrsFilter = new RemoveNSAttrsFilter();
|
||||
XMLDocumentFilter elementValidityCheckFilter = new ElementValidityCheckFilter(errorHandler);
|
||||
//XMLDocumentFilter[] filters = { removeNSAttrsFilter, elementValidityCheckFilter};
|
||||
XMLDocumentFilter[] filters = { elementValidityCheckFilter};
|
||||
|
||||
config.setErrorHandler(this.errorHandler);
|
||||
parser = new DOMParser(config);
|
||||
|
||||
// see http://nekohtml.sourceforge.net/settings.html for details
|
||||
setProperty("http://cyberneko.org/html/properties/default-encoding", java_encoding);
|
||||
setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
|
||||
setProperty("http://cyberneko.org/html/properties/names/attrs", "lower");
|
||||
setProperty("http://cyberneko.org/html/properties/filters", filters);
|
||||
setFeature("http://cyberneko.org/html/features/report-errors", true);
|
||||
setFeature("http://xml.org/sax/features/namespaces", false);
|
||||
setFeature("http://cyberneko.org/html/features/insert-doctype", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable NekoHTML feature for balancing tags in a document fragment.
|
||||
*
|
||||
* This method is used in XmlNode#in_context method.
|
||||
*/
|
||||
public void enableDocumentFragment() {
|
||||
setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XmlDocument getNewEmptyDocument(ThreadContext context) {
|
||||
IRubyObject[] args = new IRubyObject[0];
|
||||
return (XmlDocument) XmlDocument.rbNew(context, getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XmlDocument wrapDocument(ThreadContext context,
|
||||
RubyClass klazz,
|
||||
Document document) {
|
||||
HtmlDocument htmlDocument = (HtmlDocument) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), klazz);
|
||||
htmlDocument.setDocumentNode(context, document);
|
||||
if (ruby_encoding.isNil()) {
|
||||
// ruby_encoding might have detected by HtmlDocument::EncodingReader
|
||||
if (detected_encoding != null && !detected_encoding.isNil()) {
|
||||
ruby_encoding = detected_encoding;
|
||||
} else {
|
||||
// no encoding given & no encoding detected, then try to get it
|
||||
String charset = tryGetCharsetFromHtml5MetaTag(document);
|
||||
ruby_encoding = stringOrNil(context.getRuntime(), charset);
|
||||
}
|
||||
}
|
||||
htmlDocument.setEncoding(ruby_encoding);
|
||||
htmlDocument.setParsedEncoding(java_encoding);
|
||||
return htmlDocument;
|
||||
}
|
||||
|
||||
// NekoHtml doesn't understand HTML5 meta tag format. This fails to detect charset
|
||||
// from an HTML5 style meta tag. Luckily, the meta tag and charset exists in DOM tree
|
||||
// so, this method attempts to find the charset.
|
||||
private String tryGetCharsetFromHtml5MetaTag(Document document) {
|
||||
if (!"html".equalsIgnoreCase(document.getDocumentElement().getNodeName())) return null;
|
||||
NodeList list = document.getDocumentElement().getChildNodes();
|
||||
for (int i = 0; i < list.getLength(); i++) {
|
||||
if ("head".equalsIgnoreCase(list.item(i).getNodeName())) {
|
||||
NodeList headers = list.item(i).getChildNodes();
|
||||
for (int j = 0; j < headers.getLength(); j++) {
|
||||
if ("meta".equalsIgnoreCase(headers.item(j).getNodeName())) {
|
||||
NamedNodeMap nodeMap = headers.item(j).getAttributes();
|
||||
for (int k = 0; k < nodeMap.getLength(); k++) {
|
||||
if ("charset".equalsIgnoreCase(nodeMap.item(k).getNodeName())) {
|
||||
return nodeMap.item(k).getNodeValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to strip out attributes that pertain to XML namespaces.
|
||||
*/
|
||||
public static class RemoveNSAttrsFilter extends DefaultFilter {
|
||||
@Override
|
||||
public void startElement(QName element, XMLAttributes attrs,
|
||||
Augmentations augs) throws XNIException {
|
||||
int i;
|
||||
for (i = 0; i < attrs.getLength(); ++i) {
|
||||
if (isNamespace(attrs.getQName(i))) {
|
||||
attrs.removeAttributeAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
element.uri = null;
|
||||
super.startElement(element, attrs, augs);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ElementValidityCheckFilter extends DefaultFilter {
|
||||
private NokogiriErrorHandler errorHandler;
|
||||
|
||||
private ElementValidityCheckFilter(NokogiriErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
// element names from xhtml1-strict.dtd
|
||||
private static String[][] element_names = {
|
||||
{"a", "abbr", "acronym", "address", "area"},
|
||||
{"b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button"},
|
||||
{"caption", "cite", "code", "col", "colgroup"},
|
||||
{"dd", "del", "dfn", "div", "dl", "dt"},
|
||||
{"em"},
|
||||
{"fieldset", "font", "form", "frame", "frameset"},
|
||||
{}, // g
|
||||
{"h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html"},
|
||||
{"i", "iframe", "img", "input", "ins"},
|
||||
{}, // j
|
||||
{"kbd"},
|
||||
{"label", "legend", "li", "link"},
|
||||
{"map", "meta"},
|
||||
{"noframes", "noscript"},
|
||||
{"object", "ol", "optgroup", "option"},
|
||||
{"p", "param", "pre"},
|
||||
{"q"},
|
||||
{}, // r
|
||||
{"s", "samp", "script", "select", "small", "span", "strike", "strong", "style", "sub", "sup"},
|
||||
{"table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title", "tr", "tt"},
|
||||
{"u", "ul"},
|
||||
{"var"},
|
||||
{}, // w
|
||||
{}, // x
|
||||
{}, // y
|
||||
{} // z
|
||||
};
|
||||
|
||||
private boolean isValid(String testee) {
|
||||
char[] c = testee.toCharArray();
|
||||
int index = new Integer(c[0]) - 97;
|
||||
if (index > 25) return false;
|
||||
for (int i=0; i<element_names[index].length; i++) {
|
||||
if (testee.equals(element_names[index][i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(QName name, XMLAttributes attrs, Augmentations augs) throws XNIException {
|
||||
if (!isValid(name.rawname)) {
|
||||
errorHandler.getErrors().add(new Exception("Tag " + name.rawname + " invalid"));
|
||||
}
|
||||
super.startElement(name, attrs, augs);
|
||||
}
|
||||
}
|
||||
}
|
||||
322
test/fixtures/java/Hudson.java
vendored
322
test/fixtures/java/Hudson.java
vendored
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
|
||||
* Erik Ramfelt, Koichi Fujikawa, Red Hat, Inc., Seiji Sogabe,
|
||||
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder, CloudBees, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.model;
|
||||
|
||||
import hudson.ExtensionListView;
|
||||
import hudson.Functions;
|
||||
import hudson.Platform;
|
||||
import hudson.PluginManager;
|
||||
import hudson.cli.declarative.CLIResolver;
|
||||
import hudson.model.listeners.ItemListener;
|
||||
import hudson.slaves.ComputerListener;
|
||||
import hudson.util.CopyOnWriteList;
|
||||
import hudson.util.FormValidation;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jvnet.hudson.reactor.ReactorException;
|
||||
import org.kohsuke.stapler.QueryParameter;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static hudson.Util.fixEmpty;
|
||||
|
||||
public class Hudson extends Jenkins {
|
||||
|
||||
/**
|
||||
* List of registered {@link hudson.model.listeners.ItemListener}s.
|
||||
* @deprecated as of 1.286
|
||||
*/
|
||||
private transient final CopyOnWriteList<ItemListener> itemListeners = ExtensionListView.createCopyOnWriteList(ItemListener.class);
|
||||
|
||||
/**
|
||||
* List of registered {@link hudson.slaves.ComputerListener}s.
|
||||
* @deprecated as of 1.286
|
||||
*/
|
||||
private transient final CopyOnWriteList<ComputerListener> computerListeners = ExtensionListView.createCopyOnWriteList(ComputerListener.class);
|
||||
|
||||
|
||||
@CLIResolver
|
||||
public static Hudson getInstance() {
|
||||
return (Hudson)Jenkins.getInstance();
|
||||
}
|
||||
|
||||
public Hudson(File root, ServletContext context) throws IOException, InterruptedException, ReactorException {
|
||||
this(root,context,null);
|
||||
}
|
||||
|
||||
public Hudson(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException {
|
||||
super(root, context, pluginManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the installed {@link ItemListener}s.
|
||||
*
|
||||
* @deprecated as of 1.286.
|
||||
* Use {@link ItemListener#all()}.
|
||||
*/
|
||||
public CopyOnWriteList<ItemListener> getJobListeners() {
|
||||
return itemListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the installed {@link ComputerListener}s.
|
||||
*
|
||||
* @deprecated as of 1.286.
|
||||
* Use {@link ComputerListener#all()}.
|
||||
*/
|
||||
public CopyOnWriteList<ComputerListener> getComputerListeners() {
|
||||
return computerListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the slave node of the give name, hooked under this Hudson.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #getNode(String)}. Since 1.252.
|
||||
*/
|
||||
public Slave getSlave(String name) {
|
||||
Node n = getNode(name);
|
||||
if (n instanceof Slave)
|
||||
return (Slave)n;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #getNodes()}. Since 1.252.
|
||||
*/
|
||||
public List<Slave> getSlaves() {
|
||||
return (List)slaves;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the slave list.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #setNodes(List)}. Since 1.252.
|
||||
*/
|
||||
public void setSlaves(List<Slave> slaves) throws IOException {
|
||||
setNodes(slaves);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Left only for the compatibility of URLs.
|
||||
* Should not be invoked for any other purpose.
|
||||
*/
|
||||
public TopLevelItem getJob(String name) {
|
||||
return getItem(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Used only for mapping jobs to URL in a case-insensitive fashion.
|
||||
*/
|
||||
public TopLevelItem getJobCaseInsensitive(String name) {
|
||||
String match = Functions.toEmailSafeString(name);
|
||||
for(TopLevelItem item : getItems()) {
|
||||
if(Functions.toEmailSafeString(item.getName()).equalsIgnoreCase(match)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 1.317
|
||||
* Use {@link #doQuietDown()} instead.
|
||||
*/
|
||||
public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, ServletException {
|
||||
doQuietDown().generateResponse(null, rsp, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* RSS feed for log entries.
|
||||
*
|
||||
* @deprecated
|
||||
* As on 1.267, moved to "/log/rss..."
|
||||
*/
|
||||
public void doLogRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
|
||||
String qs = req.getQueryString();
|
||||
rsp.sendRedirect2("./log/rss"+(qs==null?"":'?'+qs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 1.294
|
||||
* Define your own check method, instead of relying on this generic one.
|
||||
*/
|
||||
public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
|
||||
doFieldCheck(
|
||||
fixEmpty(req.getParameter("value")),
|
||||
fixEmpty(req.getParameter("type")),
|
||||
fixEmpty(req.getParameter("errorText")),
|
||||
fixEmpty(req.getParameter("warningText"))).generateResponse(req,rsp,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value for a field is set; if not an error or warning text is displayed.
|
||||
* If the parameter "value" is not set then the parameter "errorText" is displayed
|
||||
* as an error text. If the parameter "errorText" is not set, then the parameter "warningText"
|
||||
* is displayed as a warning text.
|
||||
* <p>
|
||||
* If the text is set and the parameter "type" is set, it will validate that the value is of the
|
||||
* correct type. Supported types are "number, "number-positive" and "number-negative".
|
||||
*
|
||||
* @deprecated as of 1.324
|
||||
* Either use client-side validation (e.g. class="required number")
|
||||
* or define your own check method, instead of relying on this generic one.
|
||||
*/
|
||||
public FormValidation doFieldCheck(@QueryParameter(fixEmpty=true) String value,
|
||||
@QueryParameter(fixEmpty=true) String type,
|
||||
@QueryParameter(fixEmpty=true) String errorText,
|
||||
@QueryParameter(fixEmpty=true) String warningText) {
|
||||
if (value == null) {
|
||||
if (errorText != null)
|
||||
return FormValidation.error(errorText);
|
||||
if (warningText != null)
|
||||
return FormValidation.warning(warningText);
|
||||
return FormValidation.error("No error or warning text was set for fieldCheck().");
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
try {
|
||||
if (type.equalsIgnoreCase("number")) {
|
||||
NumberFormat.getInstance().parse(value);
|
||||
} else if (type.equalsIgnoreCase("number-positive")) {
|
||||
if (NumberFormat.getInstance().parse(value).floatValue() <= 0)
|
||||
return FormValidation.error(Messages.Hudson_NotAPositiveNumber());
|
||||
} else if (type.equalsIgnoreCase("number-negative")) {
|
||||
if (NumberFormat.getInstance().parse(value).floatValue() >= 0)
|
||||
return FormValidation.error(Messages.Hudson_NotANegativeNumber());
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
return FormValidation.error(Messages.Hudson_NotANumber());
|
||||
}
|
||||
}
|
||||
|
||||
return FormValidation.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link Functions#isWindows()}.
|
||||
*/
|
||||
public static boolean isWindows() {
|
||||
return File.pathSeparatorChar==';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link hudson.Platform#isDarwin()}
|
||||
*/
|
||||
public static boolean isDarwin() {
|
||||
return Platform.isDarwin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Use {@link #checkPermission(hudson.security.Permission)}
|
||||
*/
|
||||
public static boolean adminCheck() throws IOException {
|
||||
return adminCheck(Stapler.getCurrentRequest(), Stapler.getCurrentResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Use {@link #checkPermission(hudson.security.Permission)}
|
||||
*/
|
||||
public static boolean adminCheck(StaplerRequest req,StaplerResponse rsp) throws IOException {
|
||||
if (isAdmin(req)) return true;
|
||||
|
||||
rsp.sendError(StaplerResponse.SC_FORBIDDEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user (for which we are processing the current request)
|
||||
* has the admin access.
|
||||
*
|
||||
* @deprecated since 2007-12-18.
|
||||
* This method is deprecated when Hudson moved from simple Unix root-like model
|
||||
* of "admin gets to do everything, and others don't have any privilege" to more
|
||||
* complex {@link hudson.security.ACL} and {@link hudson.security.Permission} based scheme.
|
||||
*
|
||||
* <p>
|
||||
* For a quick migration, use {@code Hudson.getInstance().getACL().hasPermission(Hudson.ADMINISTER)}
|
||||
* To check if the user has the 'administer' role in Hudson.
|
||||
*
|
||||
* <p>
|
||||
* But ideally, your plugin should first identify a suitable {@link hudson.security.Permission} (or create one,
|
||||
* if appropriate), then identify a suitable {@link hudson.security.AccessControlled} object to check its permission
|
||||
* against.
|
||||
*/
|
||||
public static boolean isAdmin() {
|
||||
return Jenkins.getInstance().getACL().hasPermission(ADMINISTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Define a custom {@link hudson.security.Permission} and check against ACL.
|
||||
* See {@link #isAdmin()} for more instructions.
|
||||
*/
|
||||
public static boolean isAdmin(StaplerRequest req) {
|
||||
return isAdmin();
|
||||
}
|
||||
|
||||
static {
|
||||
XSTREAM.alias("hudson",Hudson.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only here for backward comp
|
||||
*/
|
||||
public static final class MasterComputer extends Jenkins.MasterComputer {
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only here for backward comp
|
||||
*/
|
||||
public static class CloudList extends Jenkins.CloudList {
|
||||
public CloudList(Jenkins h) {
|
||||
super(h);
|
||||
}
|
||||
|
||||
public CloudList() {// needed for XStream deserialization
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
598
test/fixtures/java/NokogiriService.java
vendored
598
test/fixtures/java/NokogiriService.java
vendored
@@ -1,598 +0,0 @@
|
||||
/**
|
||||
* (The MIT License)
|
||||
*
|
||||
* Copyright (c) 2008 - 2011:
|
||||
*
|
||||
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
||||
* * {Mike Dalessio}[http://mike.daless.io]
|
||||
* * {Charles Nutter}[http://blog.headius.com]
|
||||
* * {Sergio Arbeo}[http://www.serabe.com]
|
||||
* * {Patrick Mahoney}[http://polycrystal.org]
|
||||
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nokogiri;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyArray;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyFixnum;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.BasicLibraryService;
|
||||
|
||||
/**
|
||||
* Class to provide Nokogiri. This class is used to make "require 'nokogiri'" work
|
||||
* in JRuby. Also, this class holds a Ruby type cache and allocators of Ruby types.
|
||||
*
|
||||
* @author headius
|
||||
* @author Yoko Harada <yokolet@gmail.com>
|
||||
*/
|
||||
public class NokogiriService implements BasicLibraryService {
|
||||
public static final String nokogiriClassCacheGvarName = "$NOKOGIRI_CLASS_CACHE";
|
||||
public static Map<String, RubyClass> nokogiriClassCache;
|
||||
|
||||
public boolean basicLoad(Ruby ruby) {
|
||||
init(ruby);
|
||||
createNokogiriClassCahce(ruby);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void createNokogiriClassCahce(Ruby ruby) {
|
||||
nokogiriClassCache = Collections.synchronizedMap(new HashMap<String, RubyClass>());
|
||||
nokogiriClassCache.put("Nokogiri::EncodingHandler", (RubyClass)ruby.getClassFromPath("Nokogiri::EncodingHandler"));
|
||||
nokogiriClassCache.put("Nokogiri::HTML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::Document"));
|
||||
nokogiriClassCache.put("Nokogiri::HTML::ElementDescription", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::ElementDescription"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Attr", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Attr"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Document"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::DocumentFragment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DocumentFragment"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::DTD", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DTD"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Text", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Text"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Comment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Comment"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Element", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Element"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ElementContent", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementContent"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ElementDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::EntityDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::EntityReference", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityReference"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ProcessingInstruction", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ProcessingInstruction"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::CDATA", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::CDATA"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Node", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Node"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::NodeSet", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::NodeSet"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Namespace", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Namespace"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::SyntaxError", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SyntaxError"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Reader", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Reader"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::RelaxNG", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::RelaxNG"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Schema", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Schema"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::XPathContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::XPathContext"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::AttributeDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
|
||||
}
|
||||
|
||||
private void init(Ruby ruby) {
|
||||
RubyModule nokogiri = ruby.defineModule("Nokogiri");
|
||||
RubyModule xmlModule = nokogiri.defineModuleUnder("XML");
|
||||
RubyModule xmlSaxModule = xmlModule.defineModuleUnder("SAX");
|
||||
RubyModule htmlModule = nokogiri.defineModuleUnder("HTML");
|
||||
RubyModule htmlSaxModule = htmlModule.defineModuleUnder("SAX");
|
||||
RubyModule xsltModule = nokogiri.defineModuleUnder("XSLT");
|
||||
|
||||
createNokogiriModule(ruby, nokogiri);
|
||||
createSyntaxErrors(ruby, nokogiri, xmlModule);
|
||||
RubyClass xmlNode = createXmlModule(ruby, xmlModule);
|
||||
createHtmlModule(ruby, htmlModule);
|
||||
createDocuments(ruby, xmlModule, htmlModule, xmlNode);
|
||||
createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
|
||||
createXsltModule(ruby, xsltModule);
|
||||
}
|
||||
|
||||
private void createNokogiriModule(Ruby ruby, RubyModule nokogiri) {;
|
||||
RubyClass encHandler = nokogiri.defineClassUnder("EncodingHandler", ruby.getObject(), ENCODING_HANDLER_ALLOCATOR);
|
||||
encHandler.defineAnnotatedMethods(EncodingHandler.class);
|
||||
}
|
||||
|
||||
private void createSyntaxErrors(Ruby ruby, RubyModule nokogiri, RubyModule xmlModule) {
|
||||
RubyClass syntaxError = nokogiri.defineClassUnder("SyntaxError", ruby.getStandardError(), ruby.getStandardError().getAllocator());
|
||||
RubyClass xmlSyntaxError = xmlModule.defineClassUnder("SyntaxError", syntaxError, XML_SYNTAXERROR_ALLOCATOR);
|
||||
xmlSyntaxError.defineAnnotatedMethods(XmlSyntaxError.class);
|
||||
}
|
||||
|
||||
private RubyClass createXmlModule(Ruby ruby, RubyModule xmlModule) {
|
||||
RubyClass node = xmlModule.defineClassUnder("Node", ruby.getObject(), XML_NODE_ALLOCATOR);
|
||||
node.defineAnnotatedMethods(XmlNode.class);
|
||||
|
||||
RubyClass attr = xmlModule.defineClassUnder("Attr", node, XML_ATTR_ALLOCATOR);
|
||||
attr.defineAnnotatedMethods(XmlAttr.class);
|
||||
|
||||
RubyClass attrDecl = xmlModule.defineClassUnder("AttributeDecl", node, XML_ATTRIBUTE_DECL_ALLOCATOR);
|
||||
attrDecl.defineAnnotatedMethods(XmlAttributeDecl.class);
|
||||
|
||||
RubyClass characterData = xmlModule.defineClassUnder("CharacterData", node, null);
|
||||
|
||||
RubyClass comment = xmlModule.defineClassUnder("Comment", characterData, XML_COMMENT_ALLOCATOR);
|
||||
comment.defineAnnotatedMethods(XmlComment.class);
|
||||
|
||||
RubyClass text = xmlModule.defineClassUnder("Text", characterData, XML_TEXT_ALLOCATOR);
|
||||
text.defineAnnotatedMethods(XmlText.class);
|
||||
|
||||
RubyModule cdata = xmlModule.defineClassUnder("CDATA", text, XML_CDATA_ALLOCATOR);
|
||||
cdata.defineAnnotatedMethods(XmlCdata.class);
|
||||
|
||||
RubyClass dtd = xmlModule.defineClassUnder("DTD", node, XML_DTD_ALLOCATOR);
|
||||
dtd.defineAnnotatedMethods(XmlDtd.class);
|
||||
|
||||
RubyClass documentFragment = xmlModule.defineClassUnder("DocumentFragment", node, XML_DOCUMENT_FRAGMENT_ALLOCATOR);
|
||||
documentFragment.defineAnnotatedMethods(XmlDocumentFragment.class);
|
||||
|
||||
RubyClass element = xmlModule.defineClassUnder("Element", node, XML_ELEMENT_ALLOCATOR);
|
||||
element.defineAnnotatedMethods(XmlElement.class);
|
||||
|
||||
RubyClass elementContent = xmlModule.defineClassUnder("ElementContent", ruby.getObject(), XML_ELEMENT_CONTENT_ALLOCATOR);
|
||||
elementContent.defineAnnotatedMethods(XmlElementContent.class);
|
||||
|
||||
RubyClass elementDecl = xmlModule.defineClassUnder("ElementDecl", node, XML_ELEMENT_DECL_ALLOCATOR);
|
||||
elementDecl.defineAnnotatedMethods(XmlElementDecl.class);
|
||||
|
||||
RubyClass entityDecl = xmlModule.defineClassUnder("EntityDecl", node, XML_ENTITY_DECL_ALLOCATOR);
|
||||
entityDecl.defineAnnotatedMethods(XmlEntityDecl.class);
|
||||
|
||||
entityDecl.defineConstant("INTERNAL_GENERAL", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_GENERAL));
|
||||
entityDecl.defineConstant("EXTERNAL_GENERAL_PARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_PARSED));
|
||||
entityDecl.defineConstant("EXTERNAL_GENERAL_UNPARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_UNPARSED));
|
||||
entityDecl.defineConstant("INTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PARAMETER));
|
||||
entityDecl.defineConstant("EXTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_PARAMETER));
|
||||
entityDecl.defineConstant("INTERNAL_PREDEFINED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PREDEFINED));
|
||||
|
||||
RubyClass entref = xmlModule.defineClassUnder("EntityReference", node, XML_ENTITY_REFERENCE_ALLOCATOR);
|
||||
entref.defineAnnotatedMethods(XmlEntityReference.class);
|
||||
|
||||
RubyClass namespace = xmlModule.defineClassUnder("Namespace", ruby.getObject(), XML_NAMESPACE_ALLOCATOR);
|
||||
namespace.defineAnnotatedMethods(XmlNamespace.class);
|
||||
|
||||
RubyClass nodeSet = xmlModule.defineClassUnder("NodeSet", ruby.getObject(), XML_NODESET_ALLOCATOR);
|
||||
nodeSet.defineAnnotatedMethods(XmlNodeSet.class);
|
||||
|
||||
RubyClass pi = xmlModule.defineClassUnder("ProcessingInstruction", node, XML_PROCESSING_INSTRUCTION_ALLOCATOR);
|
||||
pi.defineAnnotatedMethods(XmlProcessingInstruction.class);
|
||||
|
||||
RubyClass reader = xmlModule.defineClassUnder("Reader", ruby.getObject(), XML_READER_ALLOCATOR);
|
||||
reader.defineAnnotatedMethods(XmlReader.class);
|
||||
|
||||
RubyClass schema = xmlModule.defineClassUnder("Schema", ruby.getObject(), XML_SCHEMA_ALLOCATOR);
|
||||
schema.defineAnnotatedMethods(XmlSchema.class);
|
||||
|
||||
RubyClass relaxng = xmlModule.defineClassUnder("RelaxNG", schema, XML_RELAXNG_ALLOCATOR);
|
||||
relaxng.defineAnnotatedMethods(XmlRelaxng.class);
|
||||
|
||||
RubyClass xpathContext = xmlModule.defineClassUnder("XPathContext", ruby.getObject(), XML_XPATHCONTEXT_ALLOCATOR);
|
||||
xpathContext.defineAnnotatedMethods(XmlXpathContext.class);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private void createHtmlModule(Ruby ruby, RubyModule htmlModule) {
|
||||
RubyClass htmlElemDesc = htmlModule.defineClassUnder("ElementDescription", ruby.getObject(), HTML_ELEMENT_DESCRIPTION_ALLOCATOR);
|
||||
htmlElemDesc.defineAnnotatedMethods(HtmlElementDescription.class);
|
||||
|
||||
RubyClass htmlEntityLookup = htmlModule.defineClassUnder("EntityLookup", ruby.getObject(), HTML_ENTITY_LOOKUP_ALLOCATOR);
|
||||
htmlEntityLookup.defineAnnotatedMethods(HtmlEntityLookup.class);
|
||||
}
|
||||
|
||||
private void createDocuments(Ruby ruby, RubyModule xmlModule, RubyModule htmlModule, RubyClass node) {
|
||||
RubyClass xmlDocument = xmlModule.defineClassUnder("Document", node, XML_DOCUMENT_ALLOCATOR);
|
||||
xmlDocument.defineAnnotatedMethods(XmlDocument.class);
|
||||
|
||||
//RubyModule htmlDoc = html.defineOrGetClassUnder("Document", document);
|
||||
RubyModule htmlDocument = htmlModule.defineClassUnder("Document", xmlDocument, HTML_DOCUMENT_ALLOCATOR);
|
||||
htmlDocument.defineAnnotatedMethods(HtmlDocument.class);
|
||||
}
|
||||
|
||||
private void createSaxModule(Ruby ruby, RubyModule xmlSaxModule, RubyModule htmlSaxModule) {
|
||||
RubyClass xmlSaxParserContext = xmlSaxModule.defineClassUnder("ParserContext", ruby.getObject(), XML_SAXPARSER_CONTEXT_ALLOCATOR);
|
||||
xmlSaxParserContext.defineAnnotatedMethods(XmlSaxParserContext.class);
|
||||
|
||||
RubyClass xmlSaxPushParser = xmlSaxModule.defineClassUnder("PushParser", ruby.getObject(), XML_SAXPUSHPARSER_ALLOCATOR);
|
||||
xmlSaxPushParser.defineAnnotatedMethods(XmlSaxPushParser.class);
|
||||
|
||||
RubyClass htmlSaxParserContext = htmlSaxModule.defineClassUnder("ParserContext", xmlSaxParserContext, HTML_SAXPARSER_CONTEXT_ALLOCATOR);
|
||||
htmlSaxParserContext.defineAnnotatedMethods(HtmlSaxParserContext.class);
|
||||
}
|
||||
|
||||
private void createXsltModule(Ruby ruby, RubyModule xsltModule) {
|
||||
RubyClass stylesheet = xsltModule.defineClassUnder("Stylesheet", ruby.getObject(), XSLT_STYLESHEET_ALLOCATOR);
|
||||
stylesheet.defineAnnotatedMethods(XsltStylesheet.class);
|
||||
xsltModule.defineAnnotatedMethod(XsltStylesheet.class, "register");
|
||||
}
|
||||
|
||||
private static ObjectAllocator ENCODING_HANDLER_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new EncodingHandler(runtime, klazz, "");
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator HTML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private HtmlDocument htmlDocument = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (htmlDocument == null) htmlDocument = new HtmlDocument(runtime, klazz);
|
||||
try {
|
||||
HtmlDocument clone = (HtmlDocument) htmlDocument.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new HtmlDocument(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator HTML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private HtmlSaxParserContext htmlSaxParserContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (htmlSaxParserContext == null) htmlSaxParserContext = new HtmlSaxParserContext(runtime, klazz);
|
||||
try {
|
||||
HtmlSaxParserContext clone = (HtmlSaxParserContext) htmlSaxParserContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new HtmlSaxParserContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator HTML_ELEMENT_DESCRIPTION_ALLOCATOR =
|
||||
new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new HtmlElementDescription(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator HTML_ENTITY_LOOKUP_ALLOCATOR =
|
||||
new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new HtmlEntityLookup(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_ATTR_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlAttr xmlAttr = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlAttr == null) xmlAttr = new XmlAttr(runtime, klazz);
|
||||
try {
|
||||
XmlAttr clone = (XmlAttr) xmlAttr.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlAttr(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_CDATA_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlCdata xmlCdata = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlCdata == null) xmlCdata = new XmlCdata(runtime, klazz);
|
||||
try {
|
||||
XmlCdata clone = (XmlCdata) xmlCdata.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlCdata(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_COMMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlComment xmlComment = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlComment == null) xmlComment = new XmlComment(runtime, klazz);
|
||||
try {
|
||||
XmlComment clone = (XmlComment) xmlComment.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlComment(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDocument xmlDocument = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDocument == null) xmlDocument = new XmlDocument(runtime, klazz);
|
||||
try {
|
||||
XmlDocument clone = (XmlDocument) xmlDocument.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDocument(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DOCUMENT_FRAGMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDocumentFragment xmlDocumentFragment = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDocumentFragment == null) xmlDocumentFragment = new XmlDocumentFragment(runtime, klazz);
|
||||
try {
|
||||
XmlDocumentFragment clone = (XmlDocumentFragment)xmlDocumentFragment.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDocumentFragment(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DTD_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDtd xmlDtd = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDtd == null) xmlDtd = new XmlDtd(runtime, klazz);
|
||||
try {
|
||||
XmlDtd clone = (XmlDtd)xmlDtd.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDtd(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_ELEMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlElement xmlElement = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlElement == null) xmlElement = new XmlElement(runtime, klazz);
|
||||
try {
|
||||
XmlElement clone = (XmlElement)xmlElement.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlElement(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_ELEMENT_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlElementDecl xmlElementDecl = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlElementDecl == null) xmlElementDecl = new XmlElementDecl(runtime, klazz);
|
||||
try {
|
||||
XmlElementDecl clone = (XmlElementDecl)xmlElementDecl.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlElementDecl(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_ENTITY_REFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlEntityReference xmlEntityRef = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlEntityRef == null) xmlEntityRef = new XmlEntityReference(runtime, klazz);
|
||||
try {
|
||||
XmlEntityReference clone = (XmlEntityReference)xmlEntityRef.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlEntityReference(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NAMESPACE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNamespace xmlNamespace = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNamespace == null) xmlNamespace = new XmlNamespace(runtime, klazz);
|
||||
try {
|
||||
XmlNamespace clone = (XmlNamespace) xmlNamespace.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlNamespace(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NODE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNode xmlNode = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNode == null) xmlNode = new XmlNode(runtime, klazz);
|
||||
try {
|
||||
XmlNode clone = (XmlNode) xmlNode.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlNode(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NODESET_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNodeSet xmlNodeSet = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNodeSet == null) xmlNodeSet = new XmlNodeSet(runtime, klazz);
|
||||
try {
|
||||
XmlNodeSet clone = (XmlNodeSet) xmlNodeSet.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
xmlNodeSet = new XmlNodeSet(runtime, klazz);
|
||||
xmlNodeSet.setNodes(RubyArray.newEmptyArray(runtime));
|
||||
return xmlNodeSet;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_PROCESSING_INSTRUCTION_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlProcessingInstruction xmlProcessingInstruction = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlProcessingInstruction == null) xmlProcessingInstruction = new XmlProcessingInstruction(runtime, klazz);
|
||||
try {
|
||||
XmlProcessingInstruction clone = (XmlProcessingInstruction)xmlProcessingInstruction.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlProcessingInstruction(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_READER_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlReader xmlReader = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlReader == null) xmlReader = new XmlReader(runtime, klazz);
|
||||
try {
|
||||
XmlReader clone = (XmlReader) xmlReader.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
xmlReader = new XmlReader(runtime, klazz);
|
||||
return xmlReader;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ATTRIBUTE_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlAttributeDecl(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ENTITY_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlEntityDecl(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ELEMENT_CONTENT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
throw runtime.newNotImplementedError("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_RELAXNG_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlRelaxng xmlRelaxng = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlRelaxng == null) xmlRelaxng = new XmlRelaxng(runtime, klazz);
|
||||
try {
|
||||
XmlRelaxng clone = (XmlRelaxng) xmlRelaxng.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlRelaxng(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSaxParserContext xmlSaxParserContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSaxParserContext == null) xmlSaxParserContext = new XmlSaxParserContext(runtime, klazz);
|
||||
try {
|
||||
XmlSaxParserContext clone = (XmlSaxParserContext) xmlSaxParserContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSaxParserContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlSaxPushParser(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SCHEMA_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSchema xmlSchema = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSchema == null) xmlSchema = new XmlSchema(runtime, klazz);
|
||||
try {
|
||||
XmlSchema clone = (XmlSchema) xmlSchema.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSchema(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SYNTAXERROR_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSyntaxError xmlSyntaxError = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSyntaxError == null) xmlSyntaxError = new XmlSyntaxError(runtime, klazz);
|
||||
try {
|
||||
XmlSyntaxError clone = (XmlSyntaxError) xmlSyntaxError.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSyntaxError(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_TEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlText xmlText = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlText == null) xmlText = new XmlText(runtime, klazz);
|
||||
try {
|
||||
XmlText clone = (XmlText) xmlText.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlText(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_XPATHCONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlXpathContext xmlXpathContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlXpathContext == null) xmlXpathContext = new XmlXpathContext(runtime, klazz);
|
||||
try {
|
||||
XmlXpathContext clone = (XmlXpathContext) xmlXpathContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlXpathContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XSLT_STYLESHEET_ALLOCATOR = new ObjectAllocator() {
|
||||
private XsltStylesheet xsltStylesheet = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xsltStylesheet == null) xsltStylesheet = new XsltStylesheet(runtime, klazz);
|
||||
try {
|
||||
XsltStylesheet clone = (XsltStylesheet) xsltStylesheet.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlText(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
872
test/fixtures/java/clojure-type.java
vendored
872
test/fixtures/java/clojure-type.java
vendored
@@ -1,872 +0,0 @@
|
||||
/***
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2005 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package clojure.asm;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A Java type. This class can be used to make it easier to manipulate type and
|
||||
* method descriptors.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
public class Type{
|
||||
|
||||
/**
|
||||
* The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int VOID = 0;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int BOOLEAN = 1;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int CHAR = 2;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int BYTE = 3;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int SHORT = 4;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int INT = 5;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int FLOAT = 6;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int LONG = 7;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int DOUBLE = 8;
|
||||
|
||||
/**
|
||||
* The sort of array reference types. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int ARRAY = 9;
|
||||
|
||||
/**
|
||||
* The sort of object reference type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int OBJECT = 10;
|
||||
|
||||
/**
|
||||
* The <tt>void</tt> type.
|
||||
*/
|
||||
public final static Type VOID_TYPE = new Type(VOID);
|
||||
|
||||
/**
|
||||
* The <tt>boolean</tt> type.
|
||||
*/
|
||||
public final static Type BOOLEAN_TYPE = new Type(BOOLEAN);
|
||||
|
||||
/**
|
||||
* The <tt>char</tt> type.
|
||||
*/
|
||||
public final static Type CHAR_TYPE = new Type(CHAR);
|
||||
|
||||
/**
|
||||
* The <tt>byte</tt> type.
|
||||
*/
|
||||
public final static Type BYTE_TYPE = new Type(BYTE);
|
||||
|
||||
/**
|
||||
* The <tt>short</tt> type.
|
||||
*/
|
||||
public final static Type SHORT_TYPE = new Type(SHORT);
|
||||
|
||||
/**
|
||||
* The <tt>int</tt> type.
|
||||
*/
|
||||
public final static Type INT_TYPE = new Type(INT);
|
||||
|
||||
/**
|
||||
* The <tt>float</tt> type.
|
||||
*/
|
||||
public final static Type FLOAT_TYPE = new Type(FLOAT);
|
||||
|
||||
/**
|
||||
* The <tt>long</tt> type.
|
||||
*/
|
||||
public final static Type LONG_TYPE = new Type(LONG);
|
||||
|
||||
/**
|
||||
* The <tt>double</tt> type.
|
||||
*/
|
||||
public final static Type DOUBLE_TYPE = new Type(DOUBLE);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Fields
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The sort of this Java type.
|
||||
*/
|
||||
private final int sort;
|
||||
|
||||
/**
|
||||
* A buffer containing the descriptor of this Java type. This field is only
|
||||
* used for reference types.
|
||||
*/
|
||||
private char[] buf;
|
||||
|
||||
/**
|
||||
* The offset of the descriptor of this Java type in {@link #buf buf}. This
|
||||
* field is only used for reference types.
|
||||
*/
|
||||
private int off;
|
||||
|
||||
/**
|
||||
* The length of the descriptor of this Java type.
|
||||
*/
|
||||
private int len;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a primitive type.
|
||||
*
|
||||
* @param sort the sort of the primitive type to be constructed.
|
||||
*/
|
||||
private Type(final int sort){
|
||||
this.sort = sort;
|
||||
this.len = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a reference type.
|
||||
*
|
||||
* @param sort the sort of the reference type to be constructed.
|
||||
* @param buf a buffer containing the descriptor of the previous type.
|
||||
* @param off the offset of this descriptor in the previous buffer.
|
||||
* @param len the length of this descriptor.
|
||||
*/
|
||||
private Type(final int sort, final char[] buf, final int off, final int len){
|
||||
this.sort = sort;
|
||||
this.buf = buf;
|
||||
this.off = off;
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given type descriptor.
|
||||
*
|
||||
* @param typeDescriptor a type descriptor.
|
||||
* @return the Java type corresponding to the given type descriptor.
|
||||
*/
|
||||
public static Type getType(final String typeDescriptor){
|
||||
return getType(typeDescriptor.toCharArray(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given class.
|
||||
*
|
||||
* @param c a class.
|
||||
* @return the Java type corresponding to the given class.
|
||||
*/
|
||||
public static Type getType(final Class c){
|
||||
if(c.isPrimitive())
|
||||
{
|
||||
if(c == Integer.TYPE)
|
||||
{
|
||||
return INT_TYPE;
|
||||
}
|
||||
else if(c == Void.TYPE)
|
||||
{
|
||||
return VOID_TYPE;
|
||||
}
|
||||
else if(c == Boolean.TYPE)
|
||||
{
|
||||
return BOOLEAN_TYPE;
|
||||
}
|
||||
else if(c == Byte.TYPE)
|
||||
{
|
||||
return BYTE_TYPE;
|
||||
}
|
||||
else if(c == Character.TYPE)
|
||||
{
|
||||
return CHAR_TYPE;
|
||||
}
|
||||
else if(c == Short.TYPE)
|
||||
{
|
||||
return SHORT_TYPE;
|
||||
}
|
||||
else if(c == Double.TYPE)
|
||||
{
|
||||
return DOUBLE_TYPE;
|
||||
}
|
||||
else if(c == Float.TYPE)
|
||||
{
|
||||
return FLOAT_TYPE;
|
||||
}
|
||||
else /* if (c == Long.TYPE) */
|
||||
{
|
||||
return LONG_TYPE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return getType(getDescriptor(c));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Type#OBJECT} type for the given internal class name.
|
||||
* This is a shortcut method for <code>Type.getType("L"+name+";")</code>.
|
||||
* <i>Note that opposed to {@link Type#getType(String)}, this method takes
|
||||
* internal class names and not class descriptor.</i>
|
||||
*
|
||||
* @param name an internal class name.
|
||||
* @return the the {@link Type#OBJECT} type for the given class name.
|
||||
*/
|
||||
public static Type getObjectType(String name){
|
||||
int l = name.length();
|
||||
char[] buf = new char[l + 2];
|
||||
buf[0] = 'L';
|
||||
buf[l + 1] = ';';
|
||||
name.getChars(0, l, buf, 1);
|
||||
return new Type(OBJECT, buf, 0, l + 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java types corresponding to the argument types of the given
|
||||
* method descriptor.
|
||||
*
|
||||
* @param methodDescriptor a method descriptor.
|
||||
* @return the Java types corresponding to the argument types of the given
|
||||
* method descriptor.
|
||||
*/
|
||||
public static Type[] getArgumentTypes(final String methodDescriptor){
|
||||
char[] buf = methodDescriptor.toCharArray();
|
||||
int off = 1;
|
||||
int size = 0;
|
||||
while(true)
|
||||
{
|
||||
char car = buf[off++];
|
||||
if(car == ')')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(car == 'L')
|
||||
{
|
||||
while(buf[off++] != ';')
|
||||
{
|
||||
}
|
||||
++size;
|
||||
}
|
||||
else if(car != '[')
|
||||
{
|
||||
++size;
|
||||
}
|
||||
}
|
||||
Type[] args = new Type[size];
|
||||
off = 1;
|
||||
size = 0;
|
||||
while(buf[off] != ')')
|
||||
{
|
||||
args[size] = getType(buf, off);
|
||||
off += args[size].len;
|
||||
size += 1;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java types corresponding to the argument types of the given
|
||||
* method.
|
||||
*
|
||||
* @param method a method.
|
||||
* @return the Java types corresponding to the argument types of the given
|
||||
* method.
|
||||
*/
|
||||
public static Type[] getArgumentTypes(final Method method){
|
||||
Class[] classes = method.getParameterTypes();
|
||||
Type[] types = new Type[classes.length];
|
||||
for(int i = classes.length - 1; i >= 0; --i)
|
||||
{
|
||||
types[i] = getType(classes[i]);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the return type of the given
|
||||
* method descriptor.
|
||||
*
|
||||
* @param methodDescriptor a method descriptor.
|
||||
* @return the Java type corresponding to the return type of the given
|
||||
* method descriptor.
|
||||
*/
|
||||
public static Type getReturnType(final String methodDescriptor){
|
||||
char[] buf = methodDescriptor.toCharArray();
|
||||
return getType(buf, methodDescriptor.indexOf(')') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the return type of the given
|
||||
* method.
|
||||
*
|
||||
* @param method a method.
|
||||
* @return the Java type corresponding to the return type of the given
|
||||
* method.
|
||||
*/
|
||||
public static Type getReturnType(final Method method){
|
||||
return getType(method.getReturnType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given type descriptor.
|
||||
*
|
||||
* @param buf a buffer containing a type descriptor.
|
||||
* @param off the offset of this descriptor in the previous buffer.
|
||||
* @return the Java type corresponding to the given type descriptor.
|
||||
*/
|
||||
private static Type getType(final char[] buf, final int off){
|
||||
int len;
|
||||
switch(buf[off])
|
||||
{
|
||||
case'V':
|
||||
return VOID_TYPE;
|
||||
case'Z':
|
||||
return BOOLEAN_TYPE;
|
||||
case'C':
|
||||
return CHAR_TYPE;
|
||||
case'B':
|
||||
return BYTE_TYPE;
|
||||
case'S':
|
||||
return SHORT_TYPE;
|
||||
case'I':
|
||||
return INT_TYPE;
|
||||
case'F':
|
||||
return FLOAT_TYPE;
|
||||
case'J':
|
||||
return LONG_TYPE;
|
||||
case'D':
|
||||
return DOUBLE_TYPE;
|
||||
case'[':
|
||||
len = 1;
|
||||
while(buf[off + len] == '[')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
if(buf[off + len] == 'L')
|
||||
{
|
||||
++len;
|
||||
while(buf[off + len] != ';')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
}
|
||||
return new Type(ARRAY, buf, off, len + 1);
|
||||
// case 'L':
|
||||
default:
|
||||
len = 1;
|
||||
while(buf[off + len] != ';')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
return new Type(OBJECT, buf, off, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the sort of this Java type.
|
||||
*
|
||||
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
|
||||
* {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
|
||||
* {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
|
||||
* {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
|
||||
* {@link #OBJECT OBJECT}.
|
||||
*/
|
||||
public int getSort(){
|
||||
return sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of dimensions of this array type. This method should
|
||||
* only be used for an array type.
|
||||
*
|
||||
* @return the number of dimensions of this array type.
|
||||
*/
|
||||
public int getDimensions(){
|
||||
int i = 1;
|
||||
while(buf[off + i] == '[')
|
||||
{
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the elements of this array type. This method should
|
||||
* only be used for an array type.
|
||||
*
|
||||
* @return Returns the type of the elements of this array type.
|
||||
*/
|
||||
public Type getElementType(){
|
||||
return getType(buf, off + getDimensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the class corresponding to this type.
|
||||
*
|
||||
* @return the fully qualified name of the class corresponding to this type.
|
||||
*/
|
||||
public String getClassName(){
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
return "void";
|
||||
case BOOLEAN:
|
||||
return "boolean";
|
||||
case CHAR:
|
||||
return "char";
|
||||
case BYTE:
|
||||
return "byte";
|
||||
case SHORT:
|
||||
return "short";
|
||||
case INT:
|
||||
return "int";
|
||||
case FLOAT:
|
||||
return "float";
|
||||
case LONG:
|
||||
return "long";
|
||||
case DOUBLE:
|
||||
return "double";
|
||||
case ARRAY:
|
||||
StringBuffer b = new StringBuffer(getElementType().getClassName());
|
||||
for(int i = getDimensions(); i > 0; --i)
|
||||
{
|
||||
b.append("[]");
|
||||
}
|
||||
return b.toString();
|
||||
// case OBJECT:
|
||||
default:
|
||||
return new String(buf, off + 1, len - 2).replace('/', '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal name of the class corresponding to this object type.
|
||||
* The internal name of a class is its fully qualified name, where '.' are
|
||||
* replaced by '/'. This method should only be used for an object type.
|
||||
*
|
||||
* @return the internal name of the class corresponding to this object type.
|
||||
*/
|
||||
public String getInternalName(){
|
||||
return new String(buf, off + 1, len - 2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Conversion to type descriptors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to this Java type.
|
||||
*
|
||||
* @return the descriptor corresponding to this Java type.
|
||||
*/
|
||||
public String getDescriptor(){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getDescriptor(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given argument and return
|
||||
* types.
|
||||
*
|
||||
* @param returnType the return type of the method.
|
||||
* @param argumentTypes the argument types of the method.
|
||||
* @return the descriptor corresponding to the given argument and return
|
||||
* types.
|
||||
*/
|
||||
public static String getMethodDescriptor(
|
||||
final Type returnType,
|
||||
final Type[] argumentTypes){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < argumentTypes.length; ++i)
|
||||
{
|
||||
argumentTypes[i].getDescriptor(buf);
|
||||
}
|
||||
buf.append(')');
|
||||
returnType.getDescriptor(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the descriptor corresponding to this Java type to the given
|
||||
* string buffer.
|
||||
*
|
||||
* @param buf the string buffer to which the descriptor must be appended.
|
||||
*/
|
||||
private void getDescriptor(final StringBuffer buf){
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
buf.append('V');
|
||||
return;
|
||||
case BOOLEAN:
|
||||
buf.append('Z');
|
||||
return;
|
||||
case CHAR:
|
||||
buf.append('C');
|
||||
return;
|
||||
case BYTE:
|
||||
buf.append('B');
|
||||
return;
|
||||
case SHORT:
|
||||
buf.append('S');
|
||||
return;
|
||||
case INT:
|
||||
buf.append('I');
|
||||
return;
|
||||
case FLOAT:
|
||||
buf.append('F');
|
||||
return;
|
||||
case LONG:
|
||||
buf.append('J');
|
||||
return;
|
||||
case DOUBLE:
|
||||
buf.append('D');
|
||||
return;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
buf.append(this.buf, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Direct conversion from classes to type descriptors,
|
||||
// without intermediate Type objects
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the internal name of the given class. The internal name of a
|
||||
* class is its fully qualified name, where '.' are replaced by '/'.
|
||||
*
|
||||
* @param c an object class.
|
||||
* @return the internal name of the given class.
|
||||
*/
|
||||
public static String getInternalName(final Class c){
|
||||
return c.getName().replace('.', '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given Java type.
|
||||
*
|
||||
* @param c an object class, a primitive class or an array class.
|
||||
* @return the descriptor corresponding to the given class.
|
||||
*/
|
||||
public static String getDescriptor(final Class c){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getDescriptor(buf, c);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given constructor.
|
||||
*
|
||||
* @param c a {@link Constructor Constructor} object.
|
||||
* @return the descriptor of the given constructor.
|
||||
*/
|
||||
public static String getConstructorDescriptor(final Constructor c){
|
||||
Class[] parameters = c.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < parameters.length; ++i)
|
||||
{
|
||||
getDescriptor(buf, parameters[i]);
|
||||
}
|
||||
return buf.append(")V").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given method.
|
||||
*
|
||||
* @param m a {@link Method Method} object.
|
||||
* @return the descriptor of the given method.
|
||||
*/
|
||||
public static String getMethodDescriptor(final Method m){
|
||||
Class[] parameters = m.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < parameters.length; ++i)
|
||||
{
|
||||
getDescriptor(buf, parameters[i]);
|
||||
}
|
||||
buf.append(')');
|
||||
getDescriptor(buf, m.getReturnType());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the descriptor of the given class to the given string buffer.
|
||||
*
|
||||
* @param buf the string buffer to which the descriptor must be appended.
|
||||
* @param c the class whose descriptor must be computed.
|
||||
*/
|
||||
private static void getDescriptor(final StringBuffer buf, final Class c){
|
||||
Class d = c;
|
||||
while(true)
|
||||
{
|
||||
if(d.isPrimitive())
|
||||
{
|
||||
char car;
|
||||
if(d == Integer.TYPE)
|
||||
{
|
||||
car = 'I';
|
||||
}
|
||||
else if(d == Void.TYPE)
|
||||
{
|
||||
car = 'V';
|
||||
}
|
||||
else if(d == Boolean.TYPE)
|
||||
{
|
||||
car = 'Z';
|
||||
}
|
||||
else if(d == Byte.TYPE)
|
||||
{
|
||||
car = 'B';
|
||||
}
|
||||
else if(d == Character.TYPE)
|
||||
{
|
||||
car = 'C';
|
||||
}
|
||||
else if(d == Short.TYPE)
|
||||
{
|
||||
car = 'S';
|
||||
}
|
||||
else if(d == Double.TYPE)
|
||||
{
|
||||
car = 'D';
|
||||
}
|
||||
else if(d == Float.TYPE)
|
||||
{
|
||||
car = 'F';
|
||||
}
|
||||
else /* if (d == Long.TYPE) */
|
||||
{
|
||||
car = 'J';
|
||||
}
|
||||
buf.append(car);
|
||||
return;
|
||||
}
|
||||
else if(d.isArray())
|
||||
{
|
||||
buf.append('[');
|
||||
d = d.getComponentType();
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append('L');
|
||||
String name = d.getName();
|
||||
int len = name.length();
|
||||
for(int i = 0; i < len; ++i)
|
||||
{
|
||||
char car = name.charAt(i);
|
||||
buf.append(car == '.' ? '/' : car);
|
||||
}
|
||||
buf.append(';');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Corresponding size and opcodes
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the size of values of this type.
|
||||
*
|
||||
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and
|
||||
* <tt>double</tt>, and 1 otherwise.
|
||||
*/
|
||||
public int getSize(){
|
||||
return sort == LONG || sort == DOUBLE ? 2 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JVM instruction opcode adapted to this Java type.
|
||||
*
|
||||
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
|
||||
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
|
||||
* ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
|
||||
* @return an opcode that is similar to the given opcode, but adapted to
|
||||
* this Java type. For example, if this type is <tt>float</tt> and
|
||||
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
|
||||
*/
|
||||
public int getOpcode(final int opcode){
|
||||
if(opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE)
|
||||
{
|
||||
switch(sort)
|
||||
{
|
||||
case BOOLEAN:
|
||||
case BYTE:
|
||||
return opcode + 5;
|
||||
case CHAR:
|
||||
return opcode + 6;
|
||||
case SHORT:
|
||||
return opcode + 7;
|
||||
case INT:
|
||||
return opcode;
|
||||
case FLOAT:
|
||||
return opcode + 2;
|
||||
case LONG:
|
||||
return opcode + 1;
|
||||
case DOUBLE:
|
||||
return opcode + 3;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
return opcode + 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
return opcode + 5;
|
||||
case BOOLEAN:
|
||||
case CHAR:
|
||||
case BYTE:
|
||||
case SHORT:
|
||||
case INT:
|
||||
return opcode;
|
||||
case FLOAT:
|
||||
return opcode + 2;
|
||||
case LONG:
|
||||
return opcode + 1;
|
||||
case DOUBLE:
|
||||
return opcode + 3;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
return opcode + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Equals, hashCode and toString
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Tests if the given object is equal to this type.
|
||||
*
|
||||
* @param o the object to be compared to this type.
|
||||
* @return <tt>true</tt> if the given object is equal to this type.
|
||||
*/
|
||||
public boolean equals(final Object o){
|
||||
if(this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!(o instanceof Type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Type t = (Type) o;
|
||||
if(sort != t.sort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(sort == Type.OBJECT || sort == Type.ARRAY)
|
||||
{
|
||||
if(len != t.len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(int i = off, j = t.off, end = i + len; i < end; i++, j++)
|
||||
{
|
||||
if(buf[i] != t.buf[j])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for this type.
|
||||
*
|
||||
* @return a hash code value for this type.
|
||||
*/
|
||||
public int hashCode(){
|
||||
int hc = 13 * sort;
|
||||
if(sort == Type.OBJECT || sort == Type.ARRAY)
|
||||
{
|
||||
for(int i = off, end = i + len; i < end; i++)
|
||||
{
|
||||
hc = 17 * (hc + buf[i]);
|
||||
}
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this type.
|
||||
*
|
||||
* @return the descriptor of this type.
|
||||
*/
|
||||
public String toString(){
|
||||
return getDescriptor();
|
||||
}
|
||||
}
|
||||
197
test/fixtures/java/clojure-util.java
vendored
197
test/fixtures/java/clojure-util.java
vendored
@@ -1,197 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Rich Hickey. All rights reserved.
|
||||
* The use and distribution terms for this software are covered by the
|
||||
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
||||
* which can be found in the file epl-v10.html at the root of this distribution.
|
||||
* By using this software in any fashion, you are agreeing to be bound by
|
||||
* the terms of this license.
|
||||
* You must not remove this notice, or any other, from this software.
|
||||
**/
|
||||
|
||||
/* rich Apr 19, 2008 */
|
||||
|
||||
package clojure.lang;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
public class Util{
|
||||
static public boolean equiv(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return true;
|
||||
if(k1 != null)
|
||||
{
|
||||
if(k1 instanceof Number && k2 instanceof Number)
|
||||
return Numbers.equal((Number)k1, (Number)k2);
|
||||
else if(k1 instanceof IPersistentCollection || k2 instanceof IPersistentCollection)
|
||||
return pcequiv(k1,k2);
|
||||
return k1.equals(k2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public boolean equiv(long k1, long k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, long k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(long k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(double k1, double k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, double k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(double k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(boolean k1, boolean k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, boolean k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(boolean k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(char c1, char c2) {
|
||||
return c1 == c2;
|
||||
}
|
||||
|
||||
static public boolean pcequiv(Object k1, Object k2){
|
||||
if(k1 instanceof IPersistentCollection)
|
||||
return ((IPersistentCollection)k1).equiv(k2);
|
||||
return ((IPersistentCollection)k2).equiv(k1);
|
||||
}
|
||||
|
||||
static public boolean equals(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return true;
|
||||
return k1 != null && k1.equals(k2);
|
||||
}
|
||||
|
||||
static public boolean identical(Object k1, Object k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public Class classOf(Object x){
|
||||
if(x != null)
|
||||
return x.getClass();
|
||||
return null;
|
||||
}
|
||||
|
||||
static public int compare(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return 0;
|
||||
if(k1 != null)
|
||||
{
|
||||
if(k2 == null)
|
||||
return 1;
|
||||
if(k1 instanceof Number)
|
||||
return Numbers.compare((Number) k1, (Number) k2);
|
||||
return ((Comparable) k1).compareTo(k2);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static public int hash(Object o){
|
||||
if(o == null)
|
||||
return 0;
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
static public int hasheq(Object o){
|
||||
if(o == null)
|
||||
return 0;
|
||||
if(o instanceof Number)
|
||||
return Numbers.hasheq((Number)o);
|
||||
else if(o instanceof IHashEq)
|
||||
return ((IHashEq)o).hasheq();
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
static public int hashCombine(int seed, int hash){
|
||||
//a la boost
|
||||
seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
static public boolean isPrimitive(Class c){
|
||||
return c != null && c.isPrimitive() && !(c == Void.TYPE);
|
||||
}
|
||||
|
||||
static public boolean isInteger(Object x){
|
||||
return x instanceof Integer
|
||||
|| x instanceof Long
|
||||
|| x instanceof BigInt
|
||||
|| x instanceof BigInteger;
|
||||
}
|
||||
|
||||
static public Object ret1(Object ret, Object nil){
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public ISeq ret1(ISeq ret, Object nil){
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public <K,V> void clearCache(ReferenceQueue rq, ConcurrentHashMap<K, Reference<V>> cache){
|
||||
//cleanup any dead entries
|
||||
if(rq.poll() != null)
|
||||
{
|
||||
while(rq.poll() != null)
|
||||
;
|
||||
for(Map.Entry<K, Reference<V>> e : cache.entrySet())
|
||||
{
|
||||
Reference<V> val = e.getValue();
|
||||
if(val != null && val.get() == null)
|
||||
cache.remove(e.getKey(), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public RuntimeException runtimeException(String s){
|
||||
return new RuntimeException(s);
|
||||
}
|
||||
|
||||
static public RuntimeException runtimeException(String s, Throwable e){
|
||||
return new RuntimeException(s, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw even checked exceptions without being required
|
||||
* to declare them or catch them. Suggested idiom:
|
||||
* <p>
|
||||
* <code>throw sneakyThrow( some exception );</code>
|
||||
*/
|
||||
static public RuntimeException sneakyThrow(Throwable t) {
|
||||
// http://www.mail-archive.com/javaposse@googlegroups.com/msg05984.html
|
||||
if (t == null)
|
||||
throw new NullPointerException();
|
||||
Util.<RuntimeException>sneakyThrow0(t);
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static private <T extends Throwable> void sneakyThrow0(Throwable t) throws T {
|
||||
throw (T) t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
218
test/fixtures/javascript/bootstrap-modal.js
vendored
218
test/fixtures/javascript/bootstrap-modal.js
vendored
@@ -1,218 +0,0 @@
|
||||
/* =========================================================
|
||||
* bootstrap-modal.js v2.0.4
|
||||
* http://twitter.github.com/bootstrap/javascript.html#modals
|
||||
* =========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================= */
|
||||
|
||||
|
||||
!function ($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* MODAL CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var Modal = function (content, options) {
|
||||
this.options = options
|
||||
this.$element = $(content)
|
||||
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
|
||||
}
|
||||
|
||||
Modal.prototype = {
|
||||
|
||||
constructor: Modal
|
||||
|
||||
, toggle: function () {
|
||||
return this[!this.isShown ? 'show' : 'hide']()
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var that = this
|
||||
, e = $.Event('show')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
$('body').addClass('modal-open')
|
||||
|
||||
this.isShown = true
|
||||
|
||||
escape.call(this)
|
||||
backdrop.call(this, function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
if (!that.$element.parent().length) {
|
||||
that.$element.appendTo(document.body) //don't move modals dom position
|
||||
}
|
||||
|
||||
that.$element
|
||||
.show()
|
||||
|
||||
if (transition) {
|
||||
that.$element[0].offsetWidth // force reflow
|
||||
}
|
||||
|
||||
that.$element.addClass('in')
|
||||
|
||||
transition ?
|
||||
that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
|
||||
that.$element.trigger('shown')
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
, hide: function (e) {
|
||||
e && e.preventDefault()
|
||||
|
||||
var that = this
|
||||
|
||||
e = $.Event('hide')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (!this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = false
|
||||
|
||||
$('body').removeClass('modal-open')
|
||||
|
||||
escape.call(this)
|
||||
|
||||
this.$element.removeClass('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
hideWithTransition.call(this) :
|
||||
hideModal.call(this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* MODAL PRIVATE METHODS
|
||||
* ===================== */
|
||||
|
||||
function hideWithTransition() {
|
||||
var that = this
|
||||
, timeout = setTimeout(function () {
|
||||
that.$element.off($.support.transition.end)
|
||||
hideModal.call(that)
|
||||
}, 500)
|
||||
|
||||
this.$element.one($.support.transition.end, function () {
|
||||
clearTimeout(timeout)
|
||||
hideModal.call(that)
|
||||
})
|
||||
}
|
||||
|
||||
function hideModal(that) {
|
||||
this.$element
|
||||
.hide()
|
||||
.trigger('hidden')
|
||||
|
||||
backdrop.call(this)
|
||||
}
|
||||
|
||||
function backdrop(callback) {
|
||||
var that = this
|
||||
, animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||||
|
||||
if (this.isShown && this.options.backdrop) {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
|
||||
.appendTo(document.body)
|
||||
|
||||
if (this.options.backdrop != 'static') {
|
||||
this.$backdrop.click($.proxy(this.hide, this))
|
||||
}
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
this.$backdrop.addClass('in')
|
||||
|
||||
doAnimate ?
|
||||
this.$backdrop.one($.support.transition.end, callback) :
|
||||
callback()
|
||||
|
||||
} else if (!this.isShown && this.$backdrop) {
|
||||
this.$backdrop.removeClass('in')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade')?
|
||||
this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
|
||||
removeBackdrop.call(this)
|
||||
|
||||
} else if (callback) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
function removeBackdrop() {
|
||||
this.$backdrop.remove()
|
||||
this.$backdrop = null
|
||||
}
|
||||
|
||||
function escape() {
|
||||
var that = this
|
||||
if (this.isShown && this.options.keyboard) {
|
||||
$(document).on('keyup.dismiss.modal', function ( e ) {
|
||||
e.which == 27 && that.hide()
|
||||
})
|
||||
} else if (!this.isShown) {
|
||||
$(document).off('keyup.dismiss.modal')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* MODAL PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
$.fn.modal = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('modal')
|
||||
, options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
|
||||
if (!data) $this.data('modal', (data = new Modal(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
else if (options.show) data.show()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.modal.defaults = {
|
||||
backdrop: true
|
||||
, keyboard: true
|
||||
, show: true
|
||||
}
|
||||
|
||||
$.fn.modal.Constructor = Modal
|
||||
|
||||
|
||||
/* MODAL DATA-API
|
||||
* ============== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
|
||||
var $this = $(this), href
|
||||
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||||
, option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
|
||||
|
||||
e.preventDefault()
|
||||
$target.modal(option)
|
||||
})
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
||||
46
test/fixtures/javascript/classes-old.js
vendored
46
test/fixtures/javascript/classes-old.js
vendored
@@ -1,46 +0,0 @@
|
||||
(function() {
|
||||
var Animal, Horse, Snake, sam, tom;
|
||||
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
|
||||
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
|
||||
function ctor() { this.constructor = child; }
|
||||
ctor.prototype = parent.prototype;
|
||||
child.prototype = new ctor;
|
||||
child.__super__ = parent.prototype;
|
||||
return child;
|
||||
};
|
||||
Animal = (function() {
|
||||
function Animal(name) {
|
||||
this.name = name;
|
||||
}
|
||||
Animal.prototype.move = function(meters) {
|
||||
return alert(this.name + " moved " + meters + "m.");
|
||||
};
|
||||
return Animal;
|
||||
})();
|
||||
Snake = (function() {
|
||||
__extends(Snake, Animal);
|
||||
function Snake() {
|
||||
Snake.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
Snake.prototype.move = function() {
|
||||
alert("Slithering...");
|
||||
return Snake.__super__.move.call(this, 5);
|
||||
};
|
||||
return Snake;
|
||||
})();
|
||||
Horse = (function() {
|
||||
__extends(Horse, Animal);
|
||||
function Horse() {
|
||||
Horse.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
Horse.prototype.move = function() {
|
||||
alert("Galloping...");
|
||||
return Horse.__super__.move.call(this, 45);
|
||||
};
|
||||
return Horse;
|
||||
})();
|
||||
sam = new Snake("Sammy the Python");
|
||||
tom = new Horse("Tommy the Palomino");
|
||||
sam.move();
|
||||
tom.move();
|
||||
}).call(this);
|
||||
69
test/fixtures/javascript/classes.js
vendored
69
test/fixtures/javascript/classes.js
vendored
@@ -1,69 +0,0 @@
|
||||
// Generated by CoffeeScript 1.2.1
|
||||
(function() {
|
||||
var Animal, Horse, Snake, sam, tom,
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
|
||||
|
||||
Animal = (function() {
|
||||
|
||||
Animal.name = 'Animal';
|
||||
|
||||
function Animal(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
Animal.prototype.move = function(meters) {
|
||||
return alert(this.name + " moved " + meters + "m.");
|
||||
};
|
||||
|
||||
return Animal;
|
||||
|
||||
})();
|
||||
|
||||
Snake = (function(_super) {
|
||||
|
||||
__extends(Snake, _super);
|
||||
|
||||
Snake.name = 'Snake';
|
||||
|
||||
function Snake() {
|
||||
return Snake.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
Snake.prototype.move = function() {
|
||||
alert("Slithering...");
|
||||
return Snake.__super__.move.call(this, 5);
|
||||
};
|
||||
|
||||
return Snake;
|
||||
|
||||
})(Animal);
|
||||
|
||||
Horse = (function(_super) {
|
||||
|
||||
__extends(Horse, _super);
|
||||
|
||||
Horse.name = 'Horse';
|
||||
|
||||
function Horse() {
|
||||
return Horse.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
Horse.prototype.move = function() {
|
||||
alert("Galloping...");
|
||||
return Horse.__super__.move.call(this, 45);
|
||||
};
|
||||
|
||||
return Horse;
|
||||
|
||||
})(Animal);
|
||||
|
||||
sam = new Snake("Sammy the Python");
|
||||
|
||||
tom = new Horse("Tommy the Palomino");
|
||||
|
||||
sam.move();
|
||||
|
||||
tom.move();
|
||||
|
||||
}).call(this);
|
||||
1
test/fixtures/javascript/dude.js
vendored
1
test/fixtures/javascript/dude.js
vendored
@@ -1 +0,0 @@
|
||||
alert("dude!")
|
||||
3
test/fixtures/javascript/empty.js
vendored
3
test/fixtures/javascript/empty.js
vendored
@@ -1,3 +0,0 @@
|
||||
(function() {
|
||||
|
||||
}).call(this);
|
||||
3
test/fixtures/javascript/hello.js
vendored
3
test/fixtures/javascript/hello.js
vendored
@@ -1,3 +0,0 @@
|
||||
(function() {
|
||||
console.log("Hello, World!");
|
||||
}).call(this);
|
||||
1838
test/fixtures/javascript/http.js
vendored
1838
test/fixtures/javascript/http.js
vendored
File diff suppressed because it is too large
Load Diff
37
test/fixtures/javascript/intro-old.js
vendored
37
test/fixtures/javascript/intro-old.js
vendored
@@ -1,37 +0,0 @@
|
||||
(function() {
|
||||
var cubes, list, math, num, number, opposite, race, square;
|
||||
var __slice = Array.prototype.slice;
|
||||
number = 42;
|
||||
opposite = true;
|
||||
if (opposite) {
|
||||
number = -42;
|
||||
}
|
||||
square = function(x) {
|
||||
return x * x;
|
||||
};
|
||||
list = [1, 2, 3, 4, 5];
|
||||
math = {
|
||||
root: Math.sqrt,
|
||||
square: square,
|
||||
cube: function(x) {
|
||||
return x * square(x);
|
||||
}
|
||||
};
|
||||
race = function() {
|
||||
var runners, winner;
|
||||
winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||
return print(winner, runners);
|
||||
};
|
||||
if (typeof elvis !== "undefined" && elvis !== null) {
|
||||
alert("I knew it!");
|
||||
}
|
||||
cubes = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||
num = list[_i];
|
||||
_results.push(math.cube(num));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}).call(this);
|
||||
44
test/fixtures/javascript/intro.js
vendored
44
test/fixtures/javascript/intro.js
vendored
@@ -1,44 +0,0 @@
|
||||
// Generated by CoffeeScript 1.2.1
|
||||
(function() {
|
||||
var cubes, list, math, num, number, opposite, race, square,
|
||||
__slice = [].slice;
|
||||
|
||||
number = 42;
|
||||
|
||||
opposite = true;
|
||||
|
||||
if (opposite) number = -42;
|
||||
|
||||
square = function(x) {
|
||||
return x * x;
|
||||
};
|
||||
|
||||
list = [1, 2, 3, 4, 5];
|
||||
|
||||
math = {
|
||||
root: Math.sqrt,
|
||||
square: square,
|
||||
cube: function(x) {
|
||||
return x * square(x);
|
||||
}
|
||||
};
|
||||
|
||||
race = function() {
|
||||
var runners, winner;
|
||||
winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||
return print(winner, runners);
|
||||
};
|
||||
|
||||
if (typeof elvis !== "undefined" && elvis !== null) alert("I knew it!");
|
||||
|
||||
cubes = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||
num = list[_i];
|
||||
_results.push(math.cube(num));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
154
test/fixtures/javascript/jquery-1.4.2.min.js
vendored
154
test/fixtures/javascript/jquery-1.4.2.min.js
vendored
@@ -1,154 +0,0 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v1.4.2
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Sat Feb 13 22:33:48 2010 -0500
|
||||
*/
|
||||
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
|
||||
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
|
||||
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
|
||||
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
|
||||
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
|
||||
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
|
||||
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
|
||||
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
|
||||
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
|
||||
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
|
||||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
|
||||
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
|
||||
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
|
||||
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
|
||||
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
|
||||
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
|
||||
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
|
||||
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
||||
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
|
||||
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
|
||||
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
|
||||
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
|
||||
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
|
||||
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
|
||||
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
|
||||
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
|
||||
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
|
||||
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
|
||||
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
|
||||
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
|
||||
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
|
||||
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
|
||||
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
|
||||
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
|
||||
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
|
||||
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
|
||||
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
|
||||
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
|
||||
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
|
||||
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
|
||||
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
|
||||
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
|
||||
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
|
||||
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
|
||||
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
|
||||
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
|
||||
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
|
||||
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
|
||||
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
|
||||
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
|
||||
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
|
||||
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
|
||||
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
|
||||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
|
||||
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
|
||||
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
||||
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
|
||||
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
|
||||
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
|
||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
|
||||
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
|
||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
||||
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
|
||||
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
|
||||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
|
||||
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
|
||||
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
|
||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
|
||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
|
||||
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
|
||||
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
||||
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
|
||||
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
|
||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
|
||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
|
||||
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
|
||||
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
||||
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
|
||||
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
|
||||
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
|
||||
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
|
||||
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
||||
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
|
||||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
|
||||
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
|
||||
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
|
||||
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
|
||||
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
|
||||
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
|
||||
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
|
||||
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
|
||||
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
|
||||
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
|
||||
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
|
||||
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
|
||||
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
|
||||
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
|
||||
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
|
||||
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
|
||||
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
|
||||
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
|
||||
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
|
||||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
|
||||
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
|
||||
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
|
||||
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
|
||||
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
|
||||
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
|
||||
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
|
||||
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
|
||||
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
|
||||
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
|
||||
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
|
||||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
|
||||
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
|
||||
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
|
||||
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
|
||||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
|
||||
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
|
||||
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
|
||||
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
|
||||
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
|
||||
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
|
||||
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
|
||||
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
|
||||
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
|
||||
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
|
||||
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user