//#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define FILE_SAMPLE "sample.txt" // データファイル
#define FILE_TEST "test.txt" // データファイル
#define DAT_N (500) // 1行のデータ個数
// データ
typedef struct
{
double a_data[ DAT_N] ; // a[]
char a_fname[ _MAX_PATH] ;
int b_lines;
char ** b_fname;
double ** b_data; // b[][]
double c_data[ DAT_N] ; // c[]
} ALL_DATA;
// Error コード
enum ERR_CODE
{
EDR_Normal = 0 , // 正常終了
EDR_FileOpen , // ファイルが開けない
EDR_NotEnoughData , // データが足りない
EDR_MemAlloc , // メモリ確保失敗
EDR_Zero , // 要素が全てゼロ
} ;
char * getStrERR_CODE( int code)
{
switch ( code)
{
case EDR_Normal : return "正常終了" ;
case EDR_FileOpen : return "ファイルが開けない" ;
case EDR_NotEnoughData : return "データが足りない" ;
case EDR_MemAlloc : return "メモリ確保失敗" ;
case EDR_Zero : return "要素が全てゼロ" ;
}
return "" ;
}
void aldat_init( ALL_DATA * d) ; // ALL_DATA初期化
ERR_CODE aldat_alloc( ALL_DATA * d, int lines) ; // ALL_DATA確保
void aldat_free( ALL_DATA * d) ; // ALL_DATA解放
ERR_CODE data_read( char * file1, char * file2, ALL_DATA * d) ; // データ読み込み
char * f2s_n( double d, int n) ; // 有効数字n桁小数文字列生成
#ifdef _DEBUG
#define debug_out(x) debug_file_out(x)
void debug_file_out( ALL_DATA * d) ;
#else
#define debug_out(x)
#endif
//---------------------------------------------------------------------------
// ALL_DATA初期化
//---------------------------------------------------------------------------
void aldat_init( ALL_DATA * d)
{
if ( NULL == d)
{
return ;
}
memset ( d
, 0x00 , sizeof ( ALL_DATA
) ) ; }
//---------------------------------------------------------------------------
// ALL_DATA確保
// 戻り値が EDR_Normal 以外の時は、当関数でfreeしているので呼び元でfreeしなくて良い
//---------------------------------------------------------------------------
ERR_CODE aldat_alloc( ALL_DATA * d, int lines)
{
ERR_CODE r = EDR_Normal;
int i;
// b の行数
d-> b_lines = lines;
// b
if ( NULL
== ( d
-> b_data
= ( double ** ) malloc ( sizeof ( double * ) * lines
) ) ) {
r = EDR_MemAlloc;
goto END_aldat_alloc;
}
memset ( d
-> b_data
, 0x00 , sizeof ( double * ) * lines
) ; // b[]のfilename
if ( NULL
== ( d
-> b_fname
= ( char ** ) malloc ( sizeof ( char * ) * lines
) ) ) {
r = EDR_MemAlloc;
goto END_aldat_alloc;
}
memset ( d
-> b_fname
, 0x00 , sizeof ( char * ) * lines
) ; // b[][] と b[]のfilename
for ( i= 0 ; i< lines; i++ )
{
if ( NULL
== ( d
-> b_data
[ i
] = ( double * ) malloc ( sizeof ( double ) * DAT_N
) ) ) {
r = EDR_MemAlloc;
goto END_aldat_alloc;
}
if ( NULL
== ( d
-> b_fname
[ i
] = ( char * ) malloc ( sizeof ( char ) * _MAX_PATH
) ) ) {
r = EDR_MemAlloc;
goto END_aldat_alloc;
}
}
r = EDR_Normal;
END_aldat_alloc:;
if ( EDR_Normal != r)
{
aldat_free( d) ;
}
return r;
}
//---------------------------------------------------------------------------
// ALL_DATA解放
//---------------------------------------------------------------------------
void aldat_free( ALL_DATA * d)
{
int i;
if ( NULL == d)
{
return ;
}
for ( i= 0 ; i < d-> b_lines; i++ )
{
if ( NULL == d-> b_data[ i] && NULL == d-> b_fname[ i] )
{
break ;
}
if ( d-> b_data[ i] )
{
}
if ( d-> b_fname[ i] )
{
}
}
aldat_init( d) ;
}
//---------------------------------------------------------------------------
// 関数 = データ読み込み
// 引数 = file1 : データファイル名 (sample.txt)
// file2 : データファイル名 (test.txt)
// d : データ
// 戻り値 = enum ERR_CODE;
// 注意 = ・dは呼び元で用意すること
// ・メモリ初期化/確保とエラー時の解放はは当関数でするが、
// 使用後の解放は呼び元ですること
//---------------------------------------------------------------------------
ERR_CODE data_read( char * file1, char * file2, ALL_DATA * d)
{
ERR_CODE res = EDR_Normal; // 戻り値
FILE * fp = NULL; // ファイル
char * buf = NULL; // 1行読み込みバッファ
int buf_size; // 〃 サイズ
int i, j, line; // 汎用
char * token; // 汎用
// 初期化
aldat_init( d) ;
// buf のサイズ (大きい方のファイルのサイズ)
if ( NULL
== ( fp
= fopen ( file1
, "rb" ) ) ) {
res = EDR_FileOpen;
goto END_DATAREAD;
}
if ( NULL
== ( fp
= fopen ( file2
, "rb" ) ) ) {
res = EDR_FileOpen;
goto END_DATAREAD;
}
fp = NULL;
buf_size = ( j > i) ? j : i;
// buff 確保
if ( NULL
== ( buf
= ( char * ) malloc ( buf_size
) ) ) {
res = EDR_MemAlloc;
goto END_DATAREAD;
}
// test.txt を空読みしてデータ数(行数)を数える
for ( line
= 0 ; NULL
!= fgets ( buf
, buf_size
, fp
) ; line
++ ) ; if ( line < 1 )
{
res = EDR_NotEnoughData;
goto END_DATAREAD;
}
fp = NULL;
// データ領域確保
if ( EDR_Normal != ( res = aldat_alloc( d, line) ) )
{
goto END_DATAREAD;
}
// sample.txt
fgets ( buf
, buf_size
, fp
) ; // filename
if ( NULL
== ( token
= strtok ( buf
, "\t " ) ) ) {
res = EDR_NotEnoughData;
goto END_DATAREAD;
}
strncpy ( d
-> a_fname
, token
, _MAX_PATH
) ; // data
for ( j = 0 ; j < DAT_N; j++ ) {
if ( NULL == token) {
res = EDR_NotEnoughData;
goto END_DATAREAD;
}
d
-> a_data
[ j
] = atof ( token
) ; }
fp = NULL;
// test.txt
for ( i = 0 ; i < d-> b_lines; i++ )
{
fgets ( buf
, buf_size
, fp
) ; // filename
if ( NULL
== ( token
= strtok ( buf
, "\t " ) ) ) {
res = EDR_NotEnoughData;
goto END_DATAREAD;
}
strncpy ( d
-> b_fname
[ i
] , token
, _MAX_PATH
) ; // data
for ( j = 0 ; j < DAT_N; j++ ) {
if ( NULL == token) {
res = EDR_NotEnoughData;
goto END_DATAREAD;
}
d
-> b_data
[ i
] [ j
] = atof ( token
) ; }
}
fp = NULL;
res = EDR_Normal;
END_DATAREAD:;
if ( res != EDR_Normal)
{
aldat_free( d) ;
}
if ( buf)
{
buf = NULL;
}
buf_size = 0 ;
if ( fp)
{
fp = NULL;
}
return res;
}
//---------------------------------------------------------------------------
// 関数 = 有効数字n桁小数文字列生成
// 動作 = 例えば n == 6 のとき、
// 0.0 → "0"
// 0.123456789 → "0.123457"
// 0.000123456789 → "0.000123457"
// 0.0120000 → "0.012"
// を返す
// メモ = ・n < 16
// ・未完成
//---------------------------------------------------------------------------
char * f2s_n( double d, int n)
{
static char b[ 32 ] ;
if ( d == 0.0 )
{
return "0" ;
}
return & b[ 0 ] ;
}
//---------------------------------------------------------------------------
// データ出力 (debug)
//---------------------------------------------------------------------------
#ifdef _DEBUG
void debug_file_out( ALL_DATA * d)
{
int i, j;
FILE * fp;
fp
= fopen ( "dbg_s.txt" , "w" ) ; for ( j = 0 ; j < DAT_N; j++ )
{
fprintf ( fp
, "%s\t " , f2s_n
( d
-> a_data
[ j
] , 6 ) ) ; }
fp
= fopen ( "dbg_t.txt" , "w" ) ; for ( i = 0 ; i < d-> b_lines; i++ )
{
fprintf ( fp
, "%s\t " , d
-> b_fname
[ i
] ) ; for ( j = 0 ; j < DAT_N; j++ )
{
fprintf ( fp
, "%s\t " , f2s_n
( d
-> b_data
[ i
] [ j
] , 6 ) ) ; }
}
}
#endif
//---------------------------------------------------------------------------
// main
//---------------------------------------------------------------------------
int main( )
{
int result = 0 ;
ALL_DATA data;
ERR_CODE res;
int i, j;
double v1, v2, v3;
// 初期化
aldat_init( & data) ;
// read
if ( EDR_Normal != ( res = data_read( FILE_SAMPLE, FILE_TEST, & data) ) )
{
result = ( int ) res;
goto END_MAIN;
}
// (debugモード時) 読んだデータを確認のためファイル dbg_s.txt, dbg_t.txt に書き出す
debug_out( & data) ;
// 計算
for ( i= 0 ; i < data.b_lines ; i++ )
{
v1 = v2 = v3 = 0.0 ;
for ( j= 0 ; j< DAT_N; j++ )
{
v1 += data.a_data [ j] * data.b_data [ i] [ j] ;
v2 += data.a_data [ j] * data.a_data [ j] ;
v3 += data.b_data [ i] [ j] * data.b_data [ i] [ j] ;
}
if ( v2 == 0.0 || v3 == 0.0 )
{
result = EDR_Zero;
goto END_MAIN;
}
data.
c_data [ i
] = v1
/ ( sqrt ( v2
) * sqrt ( v3
) ) ; }
// 結果
for ( i= 0 ; i < data.b_lines ; i++ )
{
printf ( "%s\t %s\n " , data.
b_fname [ i
] , f2s_n
( data.
c_data [ i
] , 15 ) ) ; }
// end
result = ( int ) EDR_Normal;
END_MAIN:;
aldat_free( & data) ;
if ( EDR_Normal != result)
{
fprintf ( stderr
, "%s\n " , getStrERR_CODE
( result
) ) ; }
return result;
}
Ly8jaW5jbHVkZSAic3RkYWZ4LmgiCiNpbmNsdWRlPHN0ZGlvLmg+CiNpbmNsdWRlPHN0ZGxpYi5oPgojaW5jbHVkZTxzdHJpbmcuaD4KI2luY2x1ZGU8bWF0aC5oPgogCiNkZWZpbmUgRklMRV9TQU1QTEUgInNhbXBsZS50eHQiICAgIC8vIOODh+ODvOOCv+ODleOCoeOCpOODqwojZGVmaW5lIEZJTEVfVEVTVCAgICJ0ZXN0LnR4dCIgICAgICAvLyDjg4fjg7zjgr/jg5XjgqHjgqTjg6sKI2RlZmluZSBEQVRfTiAoNTAwKSAgICAgICAgICAgICAgICAgLy8gMeihjOOBruODh+ODvOOCv+WAi+aVsAogCi8vIOODh+ODvOOCvwp0eXBlZGVmIHN0cnVjdAp7CiAgICBkb3VibGUgICAgICBhX2RhdGFbREFUX05dOyAgLy8gYVtdCiAgICBjaGFyICAgICAgICBhX2ZuYW1lW19NQVhfUEFUSF07CiAgICBpbnQgICAgICAgICBiX2xpbmVzOwogICAgY2hhciAqKiAgICAgYl9mbmFtZTsKICAgIGRvdWJsZSAqKiAgIGJfZGF0YTsgICAgICAgICAvLyBiW11bXQogICAgZG91YmxlICAgICAgY19kYXRhW0RBVF9OXTsgIC8vIGNbXQp9IEFMTF9EQVRBOwogCi8vIEVycm9yIOOCs+ODvOODiQplbnVtIEVSUl9DT0RFCnsKICAgIEVEUl9Ob3JtYWwgPSAwICAgICAgLCAvLyDmraPluLjntYLkuoYKICAgIEVEUl9GaWxlT3BlbiAgICAgICAgLCAvLyDjg5XjgqHjgqTjg6vjgYzplovjgZHjgarjgYQKICAgIEVEUl9Ob3RFbm91Z2hEYXRhICAgLCAvLyDjg4fjg7zjgr/jgYzotrPjgorjgarjgYQKICAgIEVEUl9NZW1BbGxvYyAgICAgICAgLCAvLyDjg6Hjg6Ljg6rnorrkv53lpLHmlZcKICAgIEVEUl9aZXJvICAgICAgICAgICAgLCAvLyDopoHntKDjgYzlhajjgabjgrzjg60KfTsKY2hhciAqZ2V0U3RyRVJSX0NPREUoaW50IGNvZGUpCnsKICAgIHN3aXRjaChjb2RlKQogICAgewogICAgY2FzZSBFRFJfTm9ybWFsICAgICAgICAgOnJldHVybiAi5q2j5bi457WC5LqGIjsKICAgIGNhc2UgRURSX0ZpbGVPcGVuICAgICAgIDpyZXR1cm4gIuODleOCoeOCpOODq+OBjOmWi+OBkeOBquOBhCI7CiAgICBjYXNlIEVEUl9Ob3RFbm91Z2hEYXRhICA6cmV0dXJuICLjg4fjg7zjgr/jgYzotrPjgorjgarjgYQiOwogICAgY2FzZSBFRFJfTWVtQWxsb2MgICAgICAgOnJldHVybiAi44Oh44Oi44Oq56K65L+d5aSx5pWXIjsKICAgIGNhc2UgRURSX1plcm8gICAgICAgICAgIDpyZXR1cm4gIuimgee0oOOBjOWFqOOBpuOCvOODrSI7CiAgICB9CiAgICByZXR1cm4gIiI7Cn0KIAp2b2lkICAgICAgICBhbGRhdF9pbml0KEFMTF9EQVRBICpkKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFMTF9EQVRB5Yid5pyf5YyWCkVSUl9DT0RFICAgIGFsZGF0X2FsbG9jKEFMTF9EQVRBICpkLCBpbnQgbGluZXMpOyAgICAgICAgICAgICAgLy8gQUxMX0RBVEHnorrkv50Kdm9pZCAgICAgICAgYWxkYXRfZnJlZShBTExfREFUQSAqZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBTExfREFUQeino+aUvgpFUlJfQ09ERSAgICBkYXRhX3JlYWQoY2hhciAqZmlsZTEsIGNoYXIgKmZpbGUyLCBBTExfREFUQSAqZCk7IC8vIOODh+ODvOOCv+iqreOBv+i+vOOBvwpjaGFyICogICAgICBmMnNfbihkb3VibGUgZCwgaW50IG4pOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIOacieWKueaVsOWtl27moYHlsI/mlbDmloflrZfliJfnlJ/miJAKIAojaWZkZWYgX0RFQlVHCiAgI2RlZmluZSBkZWJ1Z19vdXQoeCkgZGVidWdfZmlsZV9vdXQoeCkKICB2b2lkIGRlYnVnX2ZpbGVfb3V0KEFMTF9EQVRBICpkKTsKI2Vsc2UKICAjZGVmaW5lIGRlYnVnX291dCh4KQojZW5kaWYKIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBBTExfREFUQeWIneacn+WMlgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIGFsZGF0X2luaXQoQUxMX0RBVEEgKmQpCnsKICAgIGlmKE5VTEwgPT0gZCkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBtZW1zZXQoZCwgMHgwMCwgc2l6ZW9mKEFMTF9EQVRBKSk7Cn0KIAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBBTExfREFUQeeiuuS/nQovLyDmiLvjgorlgKTjgYwgRURSX05vcm1hbCDku6XlpJbjga7mmYLjga/jgIHlvZPplqLmlbDjgadmcmVl44GX44Gm44GE44KL44Gu44Gn5ZG844Gz5YWD44GnZnJlZeOBl+OBquOBj+OBpuiJr+OBhAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpFUlJfQ09ERSBhbGRhdF9hbGxvYyhBTExfREFUQSAqZCwgaW50IGxpbmVzKQp7CiAgICBFUlJfQ09ERSAgciA9IEVEUl9Ob3JtYWw7CiAgICBpbnQgaTsKIAogICAgLy8gYiDjga7ooYzmlbAKICAgIGQtPmJfbGluZXMgPSBsaW5lczsKICAgIC8vIGIKICAgIGlmKE5VTEwgPT0gKGQtPmJfZGF0YSA9IChkb3VibGUgKiopbWFsbG9jKHNpemVvZihkb3VibGUgKikgKiBsaW5lcykpKQogICAgewogICAgICAgIHIgPSBFRFJfTWVtQWxsb2M7CiAgICAgICAgZ290byBFTkRfYWxkYXRfYWxsb2M7CiAgICB9CiAgICBtZW1zZXQoZC0+Yl9kYXRhLCAweDAwLCBzaXplb2YoZG91YmxlICopICogbGluZXMpOwogICAgLy8gYltd44GuZmlsZW5hbWUKICAgIGlmKE5VTEwgPT0gKGQtPmJfZm5hbWUgPSAoY2hhciAqKiltYWxsb2Moc2l6ZW9mKGNoYXIgKikgKiBsaW5lcykpKQogICAgewogICAgICAgIHIgPSBFRFJfTWVtQWxsb2M7CiAgICAgICAgZ290byBFTkRfYWxkYXRfYWxsb2M7CiAgICB9CiAgICBtZW1zZXQoZC0+Yl9mbmFtZSwgMHgwMCwgc2l6ZW9mKGNoYXIgKikgKiBsaW5lcyk7CiAgICAvLyBiW11bXSDjgaggYltd44GuZmlsZW5hbWUKICAgIGZvcihpPTA7IGk8bGluZXM7IGkrKykKICAgIHsKICAgICAgICBpZihOVUxMID09IChkLT5iX2RhdGFbaV0gPSAoZG91YmxlICopbWFsbG9jKHNpemVvZihkb3VibGUpICogREFUX04pKSkKICAgICAgICB7CiAgICAgICAgICAgIHIgPSBFRFJfTWVtQWxsb2M7CiAgICAgICAgICAgIGdvdG8gRU5EX2FsZGF0X2FsbG9jOwogICAgICAgIH0KICAgICAgICBpZihOVUxMID09IChkLT5iX2ZuYW1lW2ldID0gKGNoYXIgKiltYWxsb2Moc2l6ZW9mKGNoYXIpICogX01BWF9QQVRIKSkpCiAgICAgICAgewogICAgICAgICAgICByID0gRURSX01lbUFsbG9jOwogICAgICAgICAgICBnb3RvIEVORF9hbGRhdF9hbGxvYzsKICAgICAgICB9CiAgICB9CiAKICAgIHIgPSBFRFJfTm9ybWFsOwpFTkRfYWxkYXRfYWxsb2M6OwogICAgaWYoRURSX05vcm1hbCAhPSByKQogICAgewogICAgICAgIGFsZGF0X2ZyZWUoZCk7CiAgICB9CiAgICByZXR1cm4gcjsKfQogCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEFMTF9EQVRB6Kej5pS+Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgYWxkYXRfZnJlZShBTExfREFUQSAqZCkKewogICAgaW50IGk7CiAKICAgIGlmKE5VTEwgPT0gZCkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmb3IoaT0wOyBpIDwgZC0+Yl9saW5lczsgaSsrKQogICAgewogICAgICAgIGlmKE5VTEwgPT0gZC0+Yl9kYXRhW2ldICYmIE5VTEwgPT0gZC0+Yl9mbmFtZVtpXSkKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZihkLT5iX2RhdGFbaV0pCiAgICAgICAgewogICAgICAgICAgICBmcmVlKGQtPmJfZGF0YVtpXSk7CiAgICAgICAgfQogICAgICAgIGlmKGQtPmJfZm5hbWVbaV0pCiAgICAgICAgewogICAgICAgICAgICBmcmVlKGQtPmJfZm5hbWVbaV0pOwogICAgICAgIH0KICAgIH0KICAgIGZyZWUoZC0+Yl9kYXRhKTsKICAgIGZyZWUoZC0+Yl9mbmFtZSk7CiAgICBhbGRhdF9pbml0KGQpOwp9CiAKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8g6Zai5pWwICAgICA9IOODh+ODvOOCv+iqreOBv+i+vOOBvwovLyDlvJXmlbAgICAgID0gZmlsZTEgIDog44OH44O844K/44OV44Kh44Kk44Or5ZCNIChzYW1wbGUudHh0KQovLyAgICAgICAgICAgIGZpbGUyICA6IOODh+ODvOOCv+ODleOCoeOCpOODq+WQjSAodGVzdC50eHQpCi8vICAgICAgICAgICAgZCAgICAgIDog44OH44O844K/Ci8vIOaIu+OCiuWApCAgID0gZW51bSBFUlJfQ09ERTsKLy8g5rOo5oSPICAgICA9IOODu2Tjga/lkbzjgbPlhYPjgafnlKjmhI/jgZnjgovjgZPjgagKLy8gICAgICAgICAgICDjg7vjg6Hjg6Ljg6rliJ3mnJ/ljJYv56K65L+d44Go44Ko44Op44O85pmC44Gu6Kej5pS+44Gv44Gv5b2T6Zai5pWw44Gn44GZ44KL44GM44CBCi8vICAgICAgICAgICAgICDkvb/nlKjlvozjga7op6PmlL7jga/lkbzjgbPlhYPjgafjgZnjgovjgZPjgagKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRVJSX0NPREUgZGF0YV9yZWFkKGNoYXIgKmZpbGUxLCBjaGFyICpmaWxlMiwgQUxMX0RBVEEgKmQpCnsKICAgIEVSUl9DT0RFIHJlcyA9IEVEUl9Ob3JtYWw7IC8vIOaIu+OCiuWApAogICAgRklMRSAqZnAgPSBOVUxMOyAgICAgICAgLy8g44OV44Kh44Kk44OrCiAgICBjaGFyICpidWYgPSBOVUxMOyAgICAgICAvLyAx6KGM6Kqt44G/6L6844G/44OQ44OD44OV44KhCiAgICBpbnQgYnVmX3NpemU7ICAgICAgICAgICAvLyAgIOOAgyAg44K144Kk44K6CiAgICBpbnQgaSwgaiwgbGluZTsgICAgICAgICAvLyDmsY7nlKgKICAgIGNoYXIgKnRva2VuOyAgICAgICAgICAgIC8vIOaxjueUqAogCiAgICAvLyDliJ3mnJ/ljJYKICAgIGFsZGF0X2luaXQoZCk7CiAKICAgIC8vIGJ1ZiDjga7jgrXjgqTjgrogKOWkp+OBjeOBhOaWueOBruODleOCoeOCpOODq+OBruOCteOCpOOCuikKICAgIGlmIChOVUxMID09IChmcCA9IGZvcGVuKGZpbGUxLCAicmIiKSkpCiAgICB7CiAgICAgICAgcmVzID0gRURSX0ZpbGVPcGVuOwogICAgICAgIGdvdG8gRU5EX0RBVEFSRUFEOwogICAgfQogICAgZnNlZWsoZnAsIDAsIFNFRUtfRU5EKTsKICAgIGkgPSAoaW50KWZ0ZWxsKGZwKSArIDE7CiAgICBmY2xvc2UoZnApOwogICAgaWYgKE5VTEwgPT0gKGZwID0gZm9wZW4oZmlsZTIsICJyYiIpKSkKICAgIHsKICAgICAgICByZXMgPSBFRFJfRmlsZU9wZW47CiAgICAgICAgZ290byBFTkRfREFUQVJFQUQ7CiAgICB9CiAgICBmc2VlayhmcCwgMCwgU0VFS19FTkQpOwogICAgaiA9IChpbnQpZnRlbGwoZnApICsgMTsKICAgIGZjbG9zZShmcCk7CiAgICBmcCA9IE5VTEw7CiAgICBidWZfc2l6ZSA9IChqID4gaSkgPyBqIDogaTsKICAgIC8vIGJ1ZmYg56K65L+dCiAgICBpZihOVUxMID09IChidWYgPSAoY2hhciopbWFsbG9jKGJ1Zl9zaXplKSkpCiAgICB7CiAgICAgICAgcmVzID0gRURSX01lbUFsbG9jOwogICAgICAgIGdvdG8gRU5EX0RBVEFSRUFEOwogICAgfQogCiAgICAvLyB0ZXN0LnR4dCDjgpLnqbroqq3jgb/jgZfjgabjg4fjg7zjgr/mlbAo6KGM5pWwKeOCkuaVsOOBiOOCiwogICAgZnAgPSBmb3BlbihmaWxlMiwgInIiKTsKICAgIGZvcihsaW5lID0gMDsgTlVMTCAhPSBmZ2V0cyhidWYsIGJ1Zl9zaXplLCBmcCk7IGxpbmUrKyk7CiAgICBpZihsaW5lIDwgMSkKICAgIHsKICAgICAgICByZXMgPSBFRFJfTm90RW5vdWdoRGF0YTsKICAgICAgICBnb3RvIEVORF9EQVRBUkVBRDsKICAgIH0KICAgIGZjbG9zZShmcCk7CiAgICBmcCA9IE5VTEw7CiAgICAvLyDjg4fjg7zjgr/poJjln5/norrkv50KICAgIGlmKEVEUl9Ob3JtYWwgIT0gKHJlcyA9IGFsZGF0X2FsbG9jKGQsIGxpbmUpKSkKICAgIHsKICAgICAgICBnb3RvIEVORF9EQVRBUkVBRDsKICAgIH0KIAogICAgLy8gc2FtcGxlLnR4dAogICAgZnAgPSBmb3BlbihmaWxlMSwgInIiKTsKICAgIGZnZXRzKGJ1ZiwgYnVmX3NpemUsIGZwKTsKICAgIC8vIGZpbGVuYW1lCiAgICBpZihOVUxMID09ICh0b2tlbiA9IHN0cnRvayhidWYsICJcdCIpKSkKICAgIHsKICAgICAgICByZXMgPSBFRFJfTm90RW5vdWdoRGF0YTsKICAgICAgICBnb3RvIEVORF9EQVRBUkVBRDsKICAgIH0KICAgIHN0cm5jcHkoZC0+YV9mbmFtZSwgdG9rZW4sIF9NQVhfUEFUSCk7CiAgICAvLyBkYXRhCiAgICBmb3IgKGogPSAwOyBqIDwgREFUX047IGorKykgewogICAgICAgIHRva2VuID0gc3RydG9rKE5VTEwsICJcdCIpOwogICAgICAgIGlmIChOVUxMID09IHRva2VuKSB7CiAgICAgICAgICAgIHJlcyA9IEVEUl9Ob3RFbm91Z2hEYXRhOwogICAgICAgICAgICBnb3RvIEVORF9EQVRBUkVBRDsKICAgICAgICB9CiAgICAgICAgZC0+YV9kYXRhW2pdID0gYXRvZih0b2tlbik7CiAgICB9CiAgICBmY2xvc2UoZnApOwogICAgZnAgPSBOVUxMOwogCiAgICAvLyB0ZXN0LnR4dAogICAgZnAgPSBmb3BlbihmaWxlMiwgInIiKTsKICAgIGZvcihpID0gMDsgaSA8IGQtPmJfbGluZXM7IGkrKykKICAgIHsKICAgICAgICBmZ2V0cyhidWYsIGJ1Zl9zaXplLCBmcCk7CiAgICAgICAgLy8gZmlsZW5hbWUKICAgICAgICBpZihOVUxMID09ICh0b2tlbiA9IHN0cnRvayhidWYsICJcdCIpKSkKICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IEVEUl9Ob3RFbm91Z2hEYXRhOwogICAgICAgICAgICBnb3RvIEVORF9EQVRBUkVBRDsKICAgICAgICB9CiAgICAgICAgc3RybmNweShkLT5iX2ZuYW1lW2ldLCB0b2tlbiwgX01BWF9QQVRIKTsKICAgICAgICAvLyBkYXRhCiAgICAgICAgZm9yIChqID0gMDsgaiA8IERBVF9OOyBqKyspIHsKICAgICAgICAgICAgdG9rZW4gPSBzdHJ0b2soTlVMTCwgIlx0Iik7CiAgICAgICAgICAgIGlmIChOVUxMID09IHRva2VuKSB7CiAgICAgICAgICAgICAgICByZXMgPSBFRFJfTm90RW5vdWdoRGF0YTsKICAgICAgICAgICAgICAgIGdvdG8gRU5EX0RBVEFSRUFEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGQtPmJfZGF0YVtpXVtqXSA9IGF0b2YodG9rZW4pOwogICAgICAgIH0KICAgIH0KICAgIGZjbG9zZShmcCk7CiAgICBmcCA9IE5VTEw7CiAKICAgIHJlcyA9IEVEUl9Ob3JtYWw7CkVORF9EQVRBUkVBRDo7CiAgICBpZihyZXMgIT0gRURSX05vcm1hbCkKICAgIHsKICAgICAgICBhbGRhdF9mcmVlKGQpOwogICAgfQogICAgaWYoYnVmKQogICAgewogICAgICAgIGZyZWUoYnVmKTsKICAgICAgICBidWYgPSBOVUxMOwogICAgfQogICAgYnVmX3NpemUgPSAwOwogICAgaWYoZnApCiAgICB7CiAgICAgICAgZmNsb3NlKGZwKTsKICAgICAgICBmcCA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CiAKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8g6Zai5pWwID0g5pyJ5Yq55pWw5a2XbuahgeWwj+aVsOaWh+Wtl+WIl+eUn+aIkAovLyDli5XkvZwgPSDkvovjgYjjgbAgbiA9PSA2IOOBruOBqOOBjeOAgQovLyAgICAgICAgICAgICAgMC4wICAgICAgICAgICAgIOKGkiAiMCIKLy8gICAgICAgICAgICAgIDAuMTIzNDU2Nzg5ICAgICDihpIgIjAuMTIzNDU3IgovLyAgICAgICAgICAgICAgMC4wMDAxMjM0NTY3ODkgIOKGkiAiMC4wMDAxMjM0NTciCi8vICAgICAgICAgICAgICAwLjAxMjAwMDAgICAgICAg4oaSICIwLjAxMiIKLy8gICAgICAgICAg44KS6L+U44GZCi8vIOODoeODoiA9IOODu24gPCAxNgovLyAgICAgICAg44O75pyq5a6M5oiQCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmNoYXIgKmYyc19uKGRvdWJsZSBkLCBpbnQgbikKewogICAgc3RhdGljIGNoYXIgYlszMl07CiAKICAgIGlmKGQgPT0gMC4wKQogICAgewogICAgICAgIHJldHVybiAiMCI7CiAgICB9CiAgICBzcHJpbnRmKGIsICIlLipmIiwgbiwgZCk7CiAKICAgIHJldHVybiAmYlswXTsKfQogCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgICAg44OH44O844K/5Ye65YqbIChkZWJ1ZykKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KI2lmZGVmIF9ERUJVRwp2b2lkIGRlYnVnX2ZpbGVfb3V0KEFMTF9EQVRBICpkKQp7CiAgICBpbnQgaSwgajsKICAgIEZJTEUgKmZwOwogCiAgICBmcCA9IGZvcGVuKCJkYmdfcy50eHQiLCAidyIpOwogICAgZnByaW50ZihmcCwgIiVzXHQiLCBkLT5hX2ZuYW1lKTsKICAgIGZvcihqID0gMDsgaiA8IERBVF9OOyBqKyspCiAgICB7CiAgICAgICAgZnByaW50ZihmcCwgIiVzXHQiLCBmMnNfbihkLT5hX2RhdGFbal0sIDYpKTsKICAgIH0KICAgIGZwcmludGYoZnAsICJcbiIpOwogICAgZmNsb3NlKGZwKTsKICAgIGZwID0gZm9wZW4oImRiZ190LnR4dCIsICJ3Iik7CiAgICBmb3IoaSA9IDA7IGkgPCBkLT5iX2xpbmVzOyBpKyspCiAgICB7CiAgICAgICAgZnByaW50ZihmcCwgIiVzXHQiLCBkLT5iX2ZuYW1lW2ldKTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBEQVRfTjsgaisrKQogICAgICAgIHsKICAgICAgICAgICAgZnByaW50ZihmcCwgIiVzXHQiLCBmMnNfbihkLT5iX2RhdGFbaV1bal0sIDYpKTsKICAgICAgICB9CiAgICAgICAgZnByaW50ZihmcCwgIlxuIik7CiAgICB9CiAgICBmY2xvc2UoZnApOwp9CiNlbmRpZgogCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgICAgbWFpbgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQppbnQgbWFpbigpCnsKICAgIGludCByZXN1bHQgPSAwOwogICAgQUxMX0RBVEEgZGF0YTsKICAgIEVSUl9DT0RFIHJlczsKICAgIGludCBpLCBqOwogICAgZG91YmxlIHYxLHYyLHYzOwogCiAgICAvLyDliJ3mnJ/ljJYKICAgIGFsZGF0X2luaXQoJmRhdGEpOwogCiAgICAvLyByZWFkCiAgICBpZihFRFJfTm9ybWFsICE9IChyZXMgPSBkYXRhX3JlYWQoRklMRV9TQU1QTEUsIEZJTEVfVEVTVCwgJmRhdGEpKSkKICAgIHsKICAgICAgICByZXN1bHQgPSAoaW50KXJlczsKICAgICAgICBnb3RvIEVORF9NQUlOOwogICAgfQogCiAgICAvLyAoZGVidWfjg6Ljg7zjg4nmmYIpIOiqreOCk+OBoOODh+ODvOOCv+OCkueiuuiqjeOBruOBn+OCgeODleOCoeOCpOODqyBkYmdfcy50eHQsIGRiZ190LnR4dCDjgavmm7jjgY3lh7rjgZkKICAgIGRlYnVnX291dCgmZGF0YSk7CiAKICAgIC8vIOioiOeulwogICAgZm9yKGk9MDsgaSA8IGRhdGEuYl9saW5lczsgaSsrKQogICAgewogICAgICAgIHYxID0gdjIgPSB2MyA9IDAuMDsKICAgICAgICBmb3Ioaj0wOyBqPCBEQVRfTjsgaisrKQogICAgICAgIHsKICAgICAgICAgICAgdjEgKz0gZGF0YS5hX2RhdGFbal0gKiBkYXRhLmJfZGF0YVtpXVtqXTsKICAgICAgICAgICAgdjIgKz0gZGF0YS5hX2RhdGFbal0gKiBkYXRhLmFfZGF0YVtqXTsKICAgICAgICAgICAgdjMgKz0gZGF0YS5iX2RhdGFbaV1bal0gKiBkYXRhLmJfZGF0YVtpXVtqXTsKICAgICAgICB9CiAgICAgICAgaWYodjIgPT0gMC4wIHx8IHYzID09IDAuMCkKICAgICAgICB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiJWTooYznm67jgIEiLCBpICsgMSk7CiAgICAgICAgICAgIHJlc3VsdCA9IEVEUl9aZXJvOwogICAgICAgICAgICBnb3RvIEVORF9NQUlOOwogICAgICAgIH0KICAgICAgICBkYXRhLmNfZGF0YVtpXSA9IHYxIC8gKHNxcnQodjIpICogc3FydCh2MykpOwogICAgfQogCiAgICAvLyDntZDmnpwKICAgIGZvcihpPTA7IGkgPCBkYXRhLmJfbGluZXM7IGkrKykKICAgIHsKICAgICAgICBwcmludGYoIiVzXHQlc1xuIiwgZGF0YS5iX2ZuYW1lW2ldLCBmMnNfbihkYXRhLmNfZGF0YVtpXSwgMTUpKTsKICAgIH0KIAogICAgLy8gZW5kCiAgICByZXN1bHQgPSAoaW50KUVEUl9Ob3JtYWw7CkVORF9NQUlOOjsKICAgIGFsZGF0X2ZyZWUoJmRhdGEpOwogICAgaWYoRURSX05vcm1hbCAhPSByZXN1bHQpCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICIlc1xuIiwgZ2V0U3RyRVJSX0NPREUocmVzdWx0KSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0Owp9