Commit 5bc104ce authored by Andrey Kamaev's avatar Andrey Kamaev

Merge branch '2.4'

parents 0e7ca71d 09abcd56
...@@ -188,7 +188,7 @@ ...@@ -188,7 +188,7 @@
{% if theme_lang == 'py' %} {% if theme_lang == 'py' %}
<li>Try the <a href="cookbook.html">Cookbook</a>.</li> <li>Try the <a href="cookbook.html">Cookbook</a>.</li>
{% endif %} {% endif %}
<li>Ask a question in the <a href="http://tech.groups.yahoo.com/group/OpenCV/">user group/mailing list</a>.</li> <li>Ask a question on the <a href="http://answers.opencv.org">Q&A forum</a>.</li>
<li>If you think something is missing or wrong in the documentation, <li>If you think something is missing or wrong in the documentation,
please file a <a href="http://code.opencv.org">bug report</a>.</li> please file a <a href="http://code.opencv.org">bug report</a>.</li>
</ul> </ul>
......
...@@ -1218,28 +1218,21 @@ namespace cv ...@@ -1218,28 +1218,21 @@ namespace cv
static int actualScalarDepth(const double* data, int len) static int actualScalarDepth(const double* data, int len)
{ {
double minval = data[0]; int i = 0, minval = INT_MAX, maxval = INT_MIN;
double maxval = data[0]; for(; i < len; ++i)
for(int i = 1; i < len; ++i) {
{ int ival = cvRound(data[i]);
minval = MIN(minval, data[i]); if( ival != data[i] )
maxval = MAX(maxval, data[i]); break;
} minval = MIN(minval, ival);
maxval = MAX(maxval, ival);
int depth = CV_64F; }
if(minval >= 0 && maxval <= UCHAR_MAX) return i < len ? CV_64F :
depth = CV_8U; minval >= 0 && maxval <= UCHAR_MAX ? CV_8U :
else if(minval >= SCHAR_MIN && maxval <= SCHAR_MAX) minval >= SCHAR_MIN && maxval <= SCHAR_MAX ? CV_8S :
depth = CV_8S; minval >= 0 && maxval <= USHRT_MAX ? CV_16U :
else if(minval >= 0 && maxval <= USHRT_MAX) minval >= SHRT_MIN && maxval <= SHRT_MAX ? CV_16S :
depth = CV_16U; CV_32S;
else if(minval >= SHRT_MIN && maxval <= SHRT_MAX)
depth = CV_16S;
else if(minval >= INT_MIN && maxval <= INT_MAX)
depth = CV_32S;
else if(minval >= -FLT_MAX && maxval <= FLT_MAX)
depth = CV_32F;
return depth;
} }
static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
...@@ -1264,7 +1257,9 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, ...@@ -1264,7 +1257,9 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
bool haveScalar = false, swapped12 = false; bool haveScalar = false, swapped12 = false;
int depth2 = src2.depth(); int depth2 = src2.depth();
if( src1.size != src2.size || src1.channels() != src2.channels() ) if( src1.size != src2.size || src1.channels() != src2.channels() ||
((kind1 == _InputArray::MATX || kind2 == _InputArray::MATX) &&
src1.cols == 1 && src2.rows == 4) )
{ {
if( checkScalar(src1, src2.type(), kind1, kind2) ) if( checkScalar(src1, src2.type(), kind1, kind2) )
{ {
...@@ -1279,10 +1274,14 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, ...@@ -1279,10 +1274,14 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
haveScalar = true; haveScalar = true;
CV_Assert(src2.type() == CV_64F && (src2.rows == 4 || src2.rows == 1)); CV_Assert(src2.type() == CV_64F && (src2.rows == 4 || src2.rows == 1));
if (usrdata == 0) // hack to filter out multiply and divide if (!muldiv)
{
depth2 = actualScalarDepth(src2.ptr<double>(), src1.channels()); depth2 = actualScalarDepth(src2.ptr<double>(), src1.channels());
if( depth2 == CV_64F && (src1.depth() < CV_32S || src1.depth() == CV_32F) )
depth2 = CV_32F;
}
else else
depth2 = CV_64F; depth2 = src1.depth() < CV_32S || src1.depth() == CV_32F ? CV_32F : CV_64F;
} }
int cn = src1.channels(), depth1 = src1.depth(), wtype; int cn = src1.channels(), depth1 = src1.depth(), wtype;
......
...@@ -42,6 +42,17 @@ ...@@ -42,6 +42,17 @@
#include "precomp.hpp" #include "precomp.hpp"
#if defined __linux__ || defined __APPLE__
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#if defined ANDROID
#include <sys/sysconf.h>
#else
#include <sys/sysctl.h>
#endif
#endif
#ifdef _OPENMP #ifdef _OPENMP
#define HAVE_OPENMP #define HAVE_OPENMP
#endif #endif
...@@ -85,7 +96,6 @@ ...@@ -85,7 +96,6 @@
#include <omp.h> #include <omp.h>
#elif defined HAVE_GCD #elif defined HAVE_GCD
#include <dispatch/dispatch.h> #include <dispatch/dispatch.h>
#include <sys/sysctl.h>
#include <pthread.h> #include <pthread.h>
#elif defined HAVE_CONCURRENCY #elif defined HAVE_CONCURRENCY
#include <ppl.h> #include <ppl.h>
......
...@@ -76,6 +76,7 @@ protected: ...@@ -76,6 +76,7 @@ protected:
bool TestVec(); bool TestVec();
bool TestMatxMultiplication(); bool TestMatxMultiplication();
bool TestSubMatAccess(); bool TestSubMatAccess();
bool TestExp();
bool TestSVD(); bool TestSVD();
bool operations1(); bool operations1();
...@@ -1003,6 +1004,17 @@ bool CV_OperationsTest::operations1() ...@@ -1003,6 +1004,17 @@ bool CV_OperationsTest::operations1()
} }
bool CV_OperationsTest::TestExp()
{
Mat1f tt = Mat1f::ones(4,2);
Mat1f outs;
exp(-tt, outs);
Mat1f tt2 = Mat1f::ones(4,1), outs2;
exp(-tt2, outs2);
return true;
}
bool CV_OperationsTest::TestSVD() bool CV_OperationsTest::TestSVD()
{ {
try try
...@@ -1079,6 +1091,9 @@ void CV_OperationsTest::run( int /* start_from */) ...@@ -1079,6 +1091,9 @@ void CV_OperationsTest::run( int /* start_from */)
if (!TestSubMatAccess()) if (!TestSubMatAccess())
return; return;
if (!TestExp())
return;
if (!TestSVD()) if (!TestSVD())
return; return;
......
...@@ -377,10 +377,13 @@ namespace cv { namespace gpu { namespace device ...@@ -377,10 +377,13 @@ namespace cv { namespace gpu { namespace device
} }
template void linearColumnFilter_gpu<float , uchar >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearColumnFilter_gpu<float , uchar >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float3, uchar3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float4, uchar4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearColumnFilter_gpu<float4, uchar4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float3, short3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearColumnFilter_gpu<float3, short3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float , int >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearColumnFilter_gpu<float , int >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearColumnFilter_gpu<float , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float3, float3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu<float4, float4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
} // namespace column_filter } // namespace column_filter
}}} // namespace cv { namespace gpu { namespace device }}} // namespace cv { namespace gpu { namespace device
......
...@@ -376,10 +376,13 @@ namespace cv { namespace gpu { namespace device ...@@ -376,10 +376,13 @@ namespace cv { namespace gpu { namespace device
} }
template void linearRowFilter_gpu<uchar , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearRowFilter_gpu<uchar , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<uchar3, float3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<uchar4, float4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearRowFilter_gpu<uchar4, float4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<short3, float3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearRowFilter_gpu<short3, float3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<int , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearRowFilter_gpu<int , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<float , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream); template void linearRowFilter_gpu<float , float >(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<float3, float3>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu<float4, float4>(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
} // namespace row_filter } // namespace row_filter
}}} // namespace cv { namespace gpu { namespace device }}} // namespace cv { namespace gpu { namespace device
......
...@@ -922,7 +922,7 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType, ...@@ -922,7 +922,7 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
int gpuBorderType; int gpuBorderType;
CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType)); CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType));
CV_Assert(srcType == CV_8UC1 || srcType == CV_8UC4 || srcType == CV_16SC3 || srcType == CV_32SC1 || srcType == CV_32FC1); CV_Assert(srcType == CV_8UC1 || srcType == CV_8UC3 || srcType == CV_8UC4 || srcType == CV_16SC3 || srcType == CV_32SC1 || srcType == CV_32FC1 || srcType == CV_32FC3 || srcType == CV_32FC4);
CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(srcType) == CV_MAT_CN(bufType)); CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(srcType) == CV_MAT_CN(bufType));
...@@ -942,6 +942,9 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType, ...@@ -942,6 +942,9 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
case CV_8UC1: case CV_8UC1:
func = linearRowFilter_gpu<uchar, float>; func = linearRowFilter_gpu<uchar, float>;
break; break;
case CV_8UC3:
func = linearRowFilter_gpu<uchar3, float3>;
break;
case CV_8UC4: case CV_8UC4:
func = linearRowFilter_gpu<uchar4, float4>; func = linearRowFilter_gpu<uchar4, float4>;
break; break;
...@@ -954,6 +957,12 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType, ...@@ -954,6 +957,12 @@ Ptr<BaseRowFilter_GPU> cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
case CV_32FC1: case CV_32FC1:
func = linearRowFilter_gpu<float, float>; func = linearRowFilter_gpu<float, float>;
break; break;
case CV_32FC3:
func = linearRowFilter_gpu<float3, float3>;
break;
case CV_32FC4:
func = linearRowFilter_gpu<float4, float4>;
break;
} }
return Ptr<BaseRowFilter_GPU>(new GpuLinearRowFilter(ksize, anchor, gpu_row_krnl, func, gpuBorderType)); return Ptr<BaseRowFilter_GPU>(new GpuLinearRowFilter(ksize, anchor, gpu_row_krnl, func, gpuBorderType));
...@@ -1034,7 +1043,7 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds ...@@ -1034,7 +1043,7 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
int gpuBorderType; int gpuBorderType;
CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType)); CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType));
CV_Assert(dstType == CV_8UC1 || dstType == CV_8UC4 || dstType == CV_16SC3 || dstType == CV_32SC1 || dstType == CV_32FC1); CV_Assert(dstType == CV_8UC1 || dstType == CV_8UC3 || dstType == CV_8UC4 || dstType == CV_16SC3 || dstType == CV_32SC1 || dstType == CV_32FC1 || dstType == CV_32FC3 || dstType == CV_32FC4);
CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(dstType) == CV_MAT_CN(bufType)); CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(dstType) == CV_MAT_CN(bufType));
...@@ -1054,6 +1063,9 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds ...@@ -1054,6 +1063,9 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
case CV_8UC1: case CV_8UC1:
func = linearColumnFilter_gpu<float, uchar>; func = linearColumnFilter_gpu<float, uchar>;
break; break;
case CV_8UC3:
func = linearColumnFilter_gpu<float3, uchar3>;
break;
case CV_8UC4: case CV_8UC4:
func = linearColumnFilter_gpu<float4, uchar4>; func = linearColumnFilter_gpu<float4, uchar4>;
break; break;
...@@ -1066,6 +1078,12 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds ...@@ -1066,6 +1078,12 @@ Ptr<BaseColumnFilter_GPU> cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
case CV_32FC1: case CV_32FC1:
func = linearColumnFilter_gpu<float, float>; func = linearColumnFilter_gpu<float, float>;
break; break;
case CV_32FC3:
func = linearColumnFilter_gpu<float3, float3>;
break;
case CV_32FC4:
func = linearColumnFilter_gpu<float4, float4>;
break;
} }
return Ptr<BaseColumnFilter_GPU>(new GpuLinearColumnFilter(ksize, anchor, gpu_col_krnl, func, gpuBorderType)); return Ptr<BaseColumnFilter_GPU>(new GpuLinearColumnFilter(ksize, anchor, gpu_col_krnl, func, gpuBorderType));
......
...@@ -152,13 +152,13 @@ TEST_P(Sobel, Accuracy) ...@@ -152,13 +152,13 @@ TEST_P(Sobel, Accuracy)
cv::Mat dst_gold; cv::Mat dst_gold;
cv::Sobel(src, dst_gold, -1, dx, dy, ksize.width, 1.0, 0.0, borderType); cv::Sobel(src, dst_gold, -1, dx, dy, ksize.width, 1.0, 0.0, borderType);
EXPECT_MAT_NEAR(dst_gold, dst, 0.0); EXPECT_MAT_NEAR(dst_gold, dst, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.1);
} }
INSTANTIATE_TEST_CASE_P(GPU_Filter, Sobel, testing::Combine( INSTANTIATE_TEST_CASE_P(GPU_Filter, Sobel, testing::Combine(
ALL_DEVICES, ALL_DEVICES,
DIFFERENT_SIZES, DIFFERENT_SIZES,
testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)), testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(KSize(cv::Size(3, 3)), KSize(cv::Size(5, 5)), KSize(cv::Size(7, 7))), testing::Values(KSize(cv::Size(3, 3)), KSize(cv::Size(5, 5)), KSize(cv::Size(7, 7))),
testing::Values(Deriv_X(0), Deriv_X(1), Deriv_X(2)), testing::Values(Deriv_X(0), Deriv_X(1), Deriv_X(2)),
testing::Values(Deriv_Y(0), Deriv_Y(1), Deriv_Y(2)), testing::Values(Deriv_Y(0), Deriv_Y(1), Deriv_Y(2)),
...@@ -208,13 +208,13 @@ TEST_P(Scharr, Accuracy) ...@@ -208,13 +208,13 @@ TEST_P(Scharr, Accuracy)
cv::Mat dst_gold; cv::Mat dst_gold;
cv::Scharr(src, dst_gold, -1, dx, dy, 1.0, 0.0, borderType); cv::Scharr(src, dst_gold, -1, dx, dy, 1.0, 0.0, borderType);
EXPECT_MAT_NEAR(dst_gold, dst, 0.0); EXPECT_MAT_NEAR(dst_gold, dst, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.1);
} }
INSTANTIATE_TEST_CASE_P(GPU_Filter, Scharr, testing::Combine( INSTANTIATE_TEST_CASE_P(GPU_Filter, Scharr, testing::Combine(
ALL_DEVICES, ALL_DEVICES,
DIFFERENT_SIZES, DIFFERENT_SIZES,
testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)), testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(Deriv_X(0), Deriv_X(1)), testing::Values(Deriv_X(0), Deriv_X(1)),
testing::Values(Deriv_Y(0), Deriv_Y(1)), testing::Values(Deriv_Y(0), Deriv_Y(1)),
testing::Values(BorderType(cv::BORDER_REFLECT101), testing::Values(BorderType(cv::BORDER_REFLECT101),
...@@ -281,7 +281,7 @@ TEST_P(GaussianBlur, Accuracy) ...@@ -281,7 +281,7 @@ TEST_P(GaussianBlur, Accuracy)
INSTANTIATE_TEST_CASE_P(GPU_Filter, GaussianBlur, testing::Combine( INSTANTIATE_TEST_CASE_P(GPU_Filter, GaussianBlur, testing::Combine(
ALL_DEVICES, ALL_DEVICES,
DIFFERENT_SIZES, DIFFERENT_SIZES,
testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)), testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(KSize(cv::Size(3, 3)), testing::Values(KSize(cv::Size(3, 3)),
KSize(cv::Size(5, 5)), KSize(cv::Size(5, 5)),
KSize(cv::Size(7, 7)), KSize(cv::Size(7, 7)),
......
This diff is collapsed.
...@@ -202,8 +202,8 @@ class RstParser(object): ...@@ -202,8 +202,8 @@ class RstParser(object):
# skip lines if line-skipping mode is activated # skip lines if line-skipping mode is activated
if skip_code_lines: if skip_code_lines:
if not l: if not l:
continue continue
if l.startswith(" "): if l.startswith(" "):
None None
else: else:
...@@ -293,19 +293,19 @@ class RstParser(object): ...@@ -293,19 +293,19 @@ class RstParser(object):
# record other lines as long description # record other lines as long description
if (skip_code_lines): if (skip_code_lines):
ll = ll.replace("/*", "/ *") ll = ll.replace("/*", "/ *")
ll = ll.replace("*/", "* /") ll = ll.replace("*/", "* /")
if (was_code_line): if (was_code_line):
func["long"] = func.get("long", "") + "\n" + ll + "\n" func["long"] = func.get("long", "") + "\n" + ll + "\n"
else: else:
was_code_line = True; was_code_line = True;
func["long"] = func.get("long", "") + ll +"\n<code>\n\n // C++ code:\n\n" func["long"] = func.get("long", "") + ll +"\n<code>\n\n // C++ code:\n\n"
else: else:
if (was_code_line): if (was_code_line):
func["long"] = func.get("long", "") + "\n" + ll + "\n</code>\n"; func["long"] = func.get("long", "") + "\n" + ll + "\n</code>\n";
was_code_line = False; was_code_line = False;
else: else:
func["long"] = func.get("long", "") + "\n" + ll func["long"] = func.get("long", "") + "\n" + ll
# endfor l in lines # endfor l in lines
if fdecl.balance != 0: if fdecl.balance != 0:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment