亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
樓主: duanjigang
打印 上一主題 下一主題

源碼閱讀第一期:axel和wget [復制鏈接]

論壇徽章:
0
81 [報告]
發(fā)表于 2011-10-01 23:42 |只看該作者
到今天為止,函數(shù)和數(shù)據(jù)結構的分析已經完成。

接下來對 搜索 和 下載 兩部分的核心函數(shù)以及代碼段做些分析,axel的分析就可以告一段落了。

論壇徽章:
0
82 [報告]
發(fā)表于 2011-10-02 10:30 |只看該作者
本帖最后由 duanjigang 于 2011-10-02 11:21 編輯

首先來看看搜索鏡像文件這段代碼:

  1. i = search_makelist( search, s );
  2.                 if( i < 0 )
  3.                 {
  4.                         fprintf( stderr, _("File not found\n" ) );
  5.                         return( 1 );
  6.                 }
  7.                 if( conf->verbose )
  8.                         printf( _("Testing speeds, this can take a while...\n") );
  9.                 //開始測速,其實就是看誰返回快
  10.                 j = search_getspeeds( search, i );
  11.                 //速度排序,按照時間由大到小排列,也就是速度由小到大排列
  12.                 search_sortlist( search, i );
復制代碼
先看看search_makelist的分析:

  1. int search_makelist( search_t *results, char *url )
  2. {
  3.         int i, size = 8192, j = 0;
  4.         char *s, *s1, *s2, *s3;
  5.         conn_t conn[1];
  6.         double t;
  7.        
  8.         memset( conn, 0, sizeof( conn_t ) );
  9.        
  10.         conn->conf = results->conf;
  11.         t = gettime();
  12.         //源站點也算一個鏡像,從此開始-----start
  13.         //填充連接的準備數(shù)據(jù)
  14.         if( !conn_set( conn, url ) )
  15.                 return( -1 );
  16.         //打開ftp或者http連接(ftp的話,要切換目錄)
  17.         if( !conn_init( conn ) )
  18.                 return( -1 );
  19.         //獲取文件信息。建立連接
  20.         if( !conn_info( conn ) )
  21.                 return( -1 );
  22.        
  23.         strcpy( results[0].url, url );
  24.         results[0].speed = 1 + 1000 * ( gettime() - t );//毫秒
  25.         results[0].size = conn->size;
  26.         //------源站點的搜索結束----finish
  27.         //因此,到目前為止,已經有一個資源鏈接了。

  28.         s = malloc( size );
  29.         //構造訪問filesearching.com的URL地址
  30.         sprintf( s, "http://www.filesearching.com/cgi-bin/s?q=%s&w=a&l=en&"
  31.                 "t=f&e=on&m=%i&o=n&s1=%lld&s2=%lld&x=15&y=15",
  32.                 conn->file, results->conf->search_amount,
  33.                 conn->size, conn->size );
  34.        
  35.         //關掉原來的連接
  36.         conn_disconnect( conn );
  37.         memset( conn, 0, sizeof( conn_t ) );
  38.         conn->conf = results->conf;
  39.         //重新設置搜索的URL地址
  40.         if( !conn_set( conn, s ) )
  41.         {
  42.                 free( s );
  43.                 //因為已經有一個搜索返回結果了,因此需要返回1
  44.                 return( 1 );
  45.         }
  46.         if( !conn_setup( conn ) )
  47.         {
  48.                 free( s );
  49.                 return( 1 );
  50.         }
  51.         if( !conn_exec( conn ) )
  52.         {
  53.                 free( s );
  54.                 return( 1 );
  55.         }
  56.         //讀取頁面返回的結果
  57.         while( ( i = read( conn->fd, s + j, size - j ) ) > 0 )
  58.         {
  59.                 j += i;
  60.                 if( j + 10 >= size )
  61.                 {
  62.                         size *= 2;
  63.                         s = realloc( s, size );
  64.                         memset( s + size / 2, 0, size / 2 );
  65.                 }
  66.         }

  67.         conn_disconnect( conn );
  68.         //關閉連接后,從http結果中解析搜索到的資源
  69.         s1 = strstr( s, "<pre class=list" );//開始標志
  70.         s1 = strchr( s1, '\n' ) + 1;
  71.         if( strstr( s1, "</pre>" ) == NULL ) //結束標志
  72.         {
  73.                 /* Incomplete list                                        */
  74.                 free( s );
  75.                 return( 1 );
  76.         }
  77.         //可以打開filesearching.com搜索一個文件后,在結果界面中查看源代碼,就能看到這個標簽
  78.         //沒發(fā)現(xiàn)</pre>就說明沒結束,還有,沒到搜索topN之前,繼續(xù)走
  79.         /*
  80.         <pre class=list>
  81.         1 <img src=/img/icontxt.gif width=16 height=16> <b>    665</b> <a href=/cgi-bin/s?t=n&l=en&q=ftp.de.debian.org/ class=ls>ftp.de.debian.org</a><a href=/cgi-bin/s?t=n&l=en&q=ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/debian-installer/amd64/boot-screens class=lg>/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/debian-installer/amd64/boot-screens/</a><a href=ftp://ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/debian-installer/amd64/boot-screens/f2.txt class=lf>f2.txt</a>
  82.         2 <img src=/img/icontxt.gif width=16 height=16> <b>    665</b> <a href=/cgi-bin/s?t=n&l=en&q=ftp.de.debian.org/ class=ls>ftp.de.debian.org</a><a href=/cgi-bin/s?t=n&l=en&q=ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/gtk/debian-installer/amd64/boot-screens class=lg>/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/gtk/debian-installer/amd64/boot-screens/</a><a href=ftp://ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/gtk/debian-installer/amd64/boot-screens/f2.txt class=lf>f2.txt</a>
  83.         </pre>
  84.         */
  85.         //結束條件: 找到結束符號 or 查找條目數(shù)夠了 or 讀取的字符串無效
  86.         for( i = 1; strncmp( s1, "</pre>", 6 ) && i < results->conf->search_amount && *s1; i ++ )
  87.         {
  88.                 s3 = strchr( s1, '\n' ); *s3 = 0;
  89.                 //最后一個href=..是文件URL
  90.                 //s2=ftp://ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/debian-installer/amd64/boot-screens/f2.txt class=lf>f2.txt</a>
  91.                 s2 = strrstr( s1, "<a href=" ) + 8;
  92.                
  93.                 *s3 = '\n';
  94.                 //找到URL后面的空格,改成結束符
  95.                 //s2變?yōu)?
  96. //ftp://ftp.de.debian.org/debian/dists/lenny/main/installer-amd64/20090123lenny8/images/netboot/debian-installer/amd64/boot-screens/f2.txt
  97. //一個完整的文件下載地址
  98.                 s3 = strchr( s2, ' ' ); *s3 = 0;
  99.                 if( strcmp( results[0].url, s2 ) )
  100.                 {
  101.                        
  102.                         strncpy( results[i].url, s2, MAX_STRING );
  103.                         results[i].size = results[0].size;
  104.                         results[i].conf = results->conf;
  105.                 }
  106.                 else
  107.                 {
  108.                         /* The original URL might show up                */
  109.                         i --;
  110.                 }
  111.                 //找到第一行結束回車符
  112.                 for( s1 = s3; *s1 != '\n'; s1 ++ );
  113.                 //第二行開頭
  114.                 s1 ++;
  115.         }
  116.        
  117.         free( s );
  118.         //返回查找到的個數(shù)
  119.         return( i );
  120. }

復制代碼

論壇徽章:
0
83 [報告]
發(fā)表于 2011-10-02 10:38 |只看該作者
回復 81# duanjigang
好快。。。。。。。

論壇徽章:
0
84 [報告]
發(fā)表于 2011-10-02 11:23 |只看該作者
回復  duanjigang
好快。。。。。。。
wangzhen11aaa 發(fā)表于 2011-10-02 10:38



    呵呵,好幾年前axel早版本的代碼大致掃過一遍,而且這個工程比較下,因此看起來快些。:wink:

論壇徽章:
0
85 [報告]
發(fā)表于 2011-10-02 11:32 |只看該作者
本帖最后由 duanjigang 于 2011-10-02 11:37 編輯

獲取search到資源的訪問速度 search_getspeeds

  1. int search_getspeeds( search_t *results, int count )
  2. {
  3.         int i, running = 0, done = 0, correct = 0;
  4.        
  5.         for( i = 0; i < count; i ++ ) if( results[i].speed )
  6.         {
  7.                
  8.                 results[i].speed_start_time = 0;
  9.                 //已經完成的個數(shù)
  10.                 done ++;
  11.                 //有效速度的個數(shù)
  12.                 if( results[i].speed > 0 )
  13.                         correct ++;
  14.         }

  15.         //沒有全部搞定之前,一直循環(huán)
  16.         while( done < count )
  17.         {
  18.                 for( i = 0; i < count; i ++ )
  19.                 {
  20.                         //未有速度值 and 搜索線程還未全部啟動起來
  21.                         if( running < results->conf->search_threads && !results[i].speed )
  22.                         {
  23.                                 results[i].speed = SPEED_ACTIVE;
  24.                                 results[i].speed_start_time = gettime();
  25.                                 if( pthread_create( results[i].speed_thread,
  26.                                         NULL, search_speedtest, &results[i] ) == 0 )
  27.                                 {
  28.                                         //一個線程又啟動啦...
  29.                                         running ++;
  30.                                         break;
  31.                                 }
  32.                                 else //如果創(chuàng)建搜索線程失敗,就直接返回
  33.                                 {
  34.                                         return( 0 );
  35.                                 }
  36.                         }//超時了,還未有速度
  37.                         else if( ( results[i].speed == SPEED_ACTIVE ) &&
  38.                                 ( gettime() > results[i].speed_start_time + results->conf->search_timeout ) )
  39.                         {
  40.                                 //停止線程
  41.                                 pthread_cancel( *results[i].speed_thread );
  42.                                 results[i].speed = SPEED_DONE;//速度小
  43.                                 running --;//減小運行線程的計數(shù)器
  44.                                 done ++; //不管成功還是失敗,總算結束了。。。
  45.                                 break; //進入下一次檢查
  46.                         }//返回了,就退出
  47.                         else //這一頭沒問題
  48.                                 if( results[i].speed > 0 && results[i].speed_start_time )
  49.                         {
  50.                                 results[i].speed_start_time = 0;
  51.                                 running --;
  52.                                 correct ++;
  53.                                 done ++;
  54.                                 break; //進入下一次檢查
  55.                         }
  56.                         else if( results[i].speed == SPEED_ERROR )//獲取失敗
  57.                         {
  58.                                 results[i].speed = SPEED_DONE;
  59.                                 running --;
  60.                                 done ++;
  61.                                 break;//進入下一次檢查
  62.                         }
  63.                 }
  64.                 //完整的檢查了一遍,就休息下,如果是中途break的,直接立刻開始下一次檢查
  65.                 if( i == count )
  66.                 {
  67.                         usleep( 100000 );
  68.                 }
  69.         }

  70.         return( correct );
  71. }
復制代碼
可以看到,測試速度是通過多線程來實現(xiàn)的,多線程的函數(shù)體是 search_speedtest

這個函數(shù)并未通過下載文件來測試速度,而是把訪問發(fā)出到返回結果的請求過程的時間間隔作為速度參考值,這是有道理的。

  1. void *search_speedtest( void *r )
  2. {
  3.         search_t *results = r;
  4.         conn_t conn[1];
  5.         int oldstate;
  6.        
  7.         /* Allow this thread to be killed at any time.                        */
  8.         pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
  9.         pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate );
  10.        
  11.         memset( conn, 0, sizeof( conn_t ) );
  12.         conn->conf = results->conf;
  13.         if( !conn_set( conn, results->url ) )
  14.                 results->speed = SPEED_ERROR;
  15.         else if( !conn_init( conn ) )
  16.                 results->speed = SPEED_ERROR;
  17.         else if( !conn_info( conn ) )
  18.                 results->speed = SPEED_ERROR;
  19.         else if( conn->size == results->size )
  20.                 /* Add one because it mustn't be zero                        */
  21.                 //時間越大,速度越小
  22.                 results->speed = 1 + 1000 * ( gettime() - results->speed_start_time );
  23.         else
  24.                 results->speed = SPEED_ERROR;

  25.         conn_disconnect( conn );
  26.        
  27.         return( NULL );
  28. }
復制代碼

論壇徽章:
0
86 [報告]
發(fā)表于 2011-10-02 11:37 |只看該作者
本帖最后由 duanjigang 于 2011-10-02 11:43 編輯

search的最后一個函數(shù) search_sortlist,鏡像站點按照速度排序


對搜索到的站點按照速度從大到小排序,也就是訪問時間從小到大排序,而axel中speed的值就是這個訪問時間間隔。

search_sortlist采用快速排序算法,當然compare函數(shù)要自己寫的。
以下兩個函數(shù)實現(xiàn)了這一切。

  1. void search_sortlist( search_t *results, int count )
  2. {
  3.         qsort( results, count, sizeof( search_t ), search_sortlist_qsort );
  4. }

  5. int search_sortlist_qsort( const void *a, const void *b )
  6. {
  7.         if( ((search_t *)a)->speed < 0 && ((search_t *)b)->speed > 0 )
  8.                 return( 1 );
  9.         if( ((search_t *)a)->speed > 0 && ((search_t *)b)->speed < 0 )
  10.                 return( -1 );
  11.         if( ((search_t *)a)->speed < ((search_t *)b)->speed )
  12.                 return( -1 );
  13.         else
  14.                 return( ((search_t *)a)->speed > ((search_t *)b)->speed );
  15. }
復制代碼
關于函數(shù)

  1. search_sortlist_qsort
復制代碼
的用意,請參考31樓的分析。

search部分的核心基本上搞定了

論壇徽章:
0
87 [報告]
發(fā)表于 2011-10-02 11:44 |只看該作者
本帖最后由 wangzhen11aaa 于 2011-10-02 16:40 編輯

<---------_______________
關于test_path_simplify()這個函數(shù)是將路徑化簡為最有效并且等價的路徑。也是為了減少運輸?shù)臄?shù)據(jù)量,具體的各個模式化簡方式以后討論。
all_tests()

. . . . . .
mu_run_test(test_append_uri_pathel);  /*1、_______________----------->/usr/url.c*/
. . . . . .
}
1、_______________-------------->
const char *test_append_uri_pathel()
{
2212 {
2213   int i;
2214   struct {
2215     char *original_url;
2216     char *input;
2217     bool escaped;
2218     char *expected_result;
2219   } test_array[] = {
2220     { "http://www.yoyodyne.com/path/", "somepage.html", false, "http://www.yoyodyne.com/path/somepage.html" },
2221   };
2222 /*這里就檢測一個url路徑*/
2223   for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)
2224     {
2225       struct growable dest; /* 此和4的一樣*/
2226       const char *p = test_array.input;
2227
2228       memset (&dest, 0, sizeof (dest));  /*這個lib庫的函數(shù)*/
2229
2230       append_string (test_array.original_url, &dest); /*2、_____________------------>/src/url.c*/
2231       append_uri_pathel (p, p + strlen(p), test_array.escaped, &dest); /*3、___________---------->*/
2232       append_char ('\0', &dest);
2233
2234       mu_assert ("test_append_uri_pathel: wrong result",
2235                  strcmp (dest.base, test_array.expected_result) == 0);
2236     }
2237
2238   return NULL;
2239 }
2、_____________---------------->
1274 static void
1275 append_string (const char *str, struct growable *dest)
1276 {
1277   int l = strlen (str);  /*獲得字符串長度*/
1278   GROW (dest, l);/*3、___________________------------->/src/url.c*/
1279   memcpy (TAIL (dest), str, l);/*7、_______------------>/src/url.c雖然分配了空間,但是還沒有賦值所以末尾值還是0*/
1280   TAIL_INCR (dest, l); /*8、___________------------->/src/url.c,改變tail 的值*/
1281 }
3、___________________------------------->
1260 #define GROW(g, append_size) do {                                            \
1261   struct growable *G_ = g;  /*4、___________------------> /src/url.c*/                                                \
1262   DO_REALLOC (G_->base, G_->size, G_->tail + append_size, char); /*5 、____---->            \
1263 } while (0)
4、______________------------->
struct growable{
char *base;
int size;  /*初始化是這些值都是0*/
int tail;
}
5、_______________------------------->
#define DO_REALLOC(basevar, sizevar, needed_size, type) do{
299   long DR_needed_size = (needed_size);    /*這里是一個式子*/                              \
300   long DR_newsize = 0;                                                  \
301   while ((sizevar) < (DR_needed_size)) {                                \
302     DR_newsize = sizevar << 1;     /* 分配的大小是2^n,至少16個字節(jié)*/                               \
303     if (DR_newsize < 16)                                                \
304       DR_newsize = 16;                                                  \
305     (sizevar) = DR_newsize;                                             \
306   }                                                                     \
307   if (DR_newsize)                                                       \
308     basevar = xrealloc (basevar, DR_newsize * sizeof (type));  /*分配大小,這里出現(xiàn)了c++的類和c,當然我選擇的是c6、____---------->lib/xmalloc.c*/         /*type 本來就是char 類型,為什么還要sizeof(type)?我覺得為了少出人為的錯*/\
309 } while (0)
310
6、_______-------------->
52 void *
53 xrealloc (void *p, size_t n)
54 {
55   if (!n && p)
56     {
57      
59       free (p);
60       return NULL;
61     }
62
63   p = realloc (p, n);    /*分配在這里*/
64   if (!p && n)
65     xalloc_die ();  /*abort()*/
66   return p;
67 }
<---------------------------____________________________
GROW調用后,dest被初始化,類型中既有地址,而且有大小*/
7、_______________---------------->
#define TAIL(r) ((r)->base + (r)->tail)
8、_______------------>
#define  #define TAIL_INCR(r, append_count) ((r)->tail += append_count)
<------------------------------------______________________________________________
返回到 mu_run_test(test_append_uri_pathel()函數(shù)中
append_uri_pathel() _________----------->9、/src/url.c*/
1372 static void
1373 append_uri_pathel (const char *b, const char *e, bool escaped,
1374                    struct growable *dest)
1375 {
1376   const char *p;
1377   int quoted, outlen;
1378
1379   int mask;
1380   if (opt.restrict_files_os == restrict_unix)
1381     mask = filechr_not_unix;  /*判斷unix類型*/
1382   else
1383     mask = filechr_not_windows;  
1384   if (opt.restrict_files_ctrl)
1385     mask |= filechr_control;
1386
1387  
1388   if (escaped)  /*如果期望值是1*/
1389     {
1390       char *unescaped;   
1391       BOUNDED_TO_ALLOCA (b, e, unescaped);/*10、______------->/src/wget.h*/
1392       url_unescape (unescaped);
1393       b = unescaped;
1394       e = unescaped + strlen (unescaped);
1395     }
1396
1397  
1398   
1399   if (e - b == 2 && b[0] == '.' && b[1] == '.')
1400     {
1401       b = "%2E%2E";
1402       e = b + 6;
1403     }
1404
1407   quoted = 0;
1408   for (p = b; p < e; p++)
1409     if (FILE_CHAR_TEST (*p, mask))
1410       ++quoted;
1411
1412   /* Calculate the length of the output string.  e-b is the input
1413      string length.  Each quoted char introduces two additional
1414      characters in the string, hence 2*quoted.  */
1415   outlen = (e - b) + (2 * quoted);
1416   GROW (dest, outlen);
1417
1418   if (!quoted)
1419     {
1420      
1421
1422       memcpy (TAIL (dest), b, outlen);
1423     }
1424   else
1425     {
1426       char *q = TAIL (dest);
1427       for (p = b; p < e; p++)
1428         {
1429           if (!FILE_CHAR_TEST (*p, mask))
1430             *q++ = *p;
1431           else
1432             {
1433               unsigned char ch = *p;
1434               *q++ = '%';
1435               *q++ = XNUM_TO_DIGIT (ch >> 4);
1436               *q++ = XNUM_TO_DIGIT (ch & 0xf);
1437             }
1438         }
1439       assert (q - TAIL (dest) == outlen);
1440  }
1443   if (opt.restrict_files_case == restrict_lowercase
1444       || opt.restrict_files_case == restrict_uppercase)
1445     {
1446       char *q;
1447       for (q = TAIL (dest); q < TAIL (dest) + outlen; ++q)
1448         {
1449           if (opt.restrict_files_case == restrict_lowercase)
1450             *q = c_tolower (*q);
1451           else
1452             *q = c_toupper (*q);
1453         }
1454     }
1455
1456   TAIL_INCR (dest, outlen);
1457 }
10、____________------------>
#define BOUNDED_TO_ALLOC(beg, end, place)   \
要裝不下了。下移*/

論壇徽章:
0
88 [報告]
發(fā)表于 2011-10-02 17:22 |只看該作者
接著
257 #define BOUNDED_TO_ALLOCA(beg, end, place) do { \  
258   const char *BTA_beg = (beg);                  \
259   int BTA_len = (end) - BTA_beg;                \
260   char **BTA_dest = &(place);                   \
261   *BTA_dest = alloca (BTA_len + 1);             \/*alloca的作用是測試并返回堆棧空間的*/
262   memcpy (*BTA_dest, BTA_beg, BTA_len);         \
263   (*BTA_dest)[BTA_len] = '\0';                  \/*字符串末尾加\0*/
264 } while (0)
這段函數(shù)作用是在place指針指向位置拷貝字符串
<-------------------_____________
下面的函數(shù)為 url_unescape(char *s)  /*0、__________--------->/src/url.c*/
172 static void
173 url_unescape (char *s)
174 {
175   char *t = s;               
176   char *h = s;                 
177
178   for (; *h; h++, t++)  /*直到到達字符串的末尾*/
179     {
180       if (*h != '%')
181         {
182         copychar:            /*此處準備使用goto語句*/
183           *t = *h;   /*如果*h不是%,那么就拷貝到*t指向的位置*/
184         }
185       else
186         {
187           char c;
188           /* Do nothing if '%' is not followed by two hex digits. 如果%號后沒有兩個16進制的數(shù)*/
189           if (!h[1] || !h[2] || !(c_isxdigit (h[1]) && c_isxdigit (h[2]))) /*1、__-->lib/c-type.c*/
190             goto copychar;  /*就去拷貝*/
191           c = X2DIGITS_TO_NUM (h[1], h[2]); /*3、_______----->/src/wget.h*/
192           /* Don't unescape %00 because there is no way to insert it
193              into a C string without effectively truncating it. */
194           if (c == '\0')
195             goto copychar;
196           *t = c;
197           h += 2;
198         }
199     }
200   *t = '\0';
201 }
1、________--------->
效果很明顯,不解釋了*/
296 c_isxdigit (int c)
297 {
298 #if C_CTYPE_CONSECUTIVE_DIGITS \
299     && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
300 #if C_CTYPE_ASCII
301   return ((c >= '0' && c <= '9')
302           || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));
303 #else
304   return ((c >= '0' && c <= '9')
305           || (c >= 'A' && c <= 'F')
306           || (c >= 'a' && c <= 'f'));
307 #endif
308 #else
309   switch (c)
310     {
311     case '0': case '1': case '2': case '3': case '4': case '5':
312     case '6': case '7': case '8': case '9':
313     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
314     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
315       return 1;
316     default:
317       return 0;
318     }
319 #endif
320 }
3、__________---------->
#define ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2))  /*通知一下,這里的源代碼中是XDIGT_TO是錯誤的,在/src/wget.h中246行*/
#define XDIGIT_TO_NUM(h) ((h) < 'A' ? (h) - '0' : c_toupper(h) - 'A' + 10)

論壇徽章:
0
89 [報告]
發(fā)表于 2011-10-02 17:26 |只看該作者
本帖最后由 wangzhen11aaa 于 2011-10-02 19:49 編輯

通知                                 
#define ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2))  /*通知一下,這里的源代碼中是XDIGT_TO是錯誤的,在/src/wget.h中246行*/

而且 :
好像有段程序有問題。
173 url_unescape (char *s)
174 {
175   char *t = s;                  /* t - tortoise */
176   char *h = s;                  /* h - hare     */
177
178   for (; *h; h++, t++)
179     {
180       if (*h != '%')
181         {
182         copychar:
183           *t = *h;
                                       /*這里我認為應該有個continue;*/
184         }
185       else
186         {                /*這里如果字符是%,而且后面的h[1]h[2]都是16進制的,那么不是會陷入死循環(huán)嗎?*/
187           char c;
188           /* Do nothing if '%' is not followed by two hex digits. */
189           if (!h[1] || !h[2] || !(c_isxdigit (h[1]) && c_isxdigit (h[2])))
190             goto copychar;  /*這里goto copychar 了, 然后一直執(zhí)行h[1]h[2]是16進制的判斷?不是死循環(huán)嗎?*/
191           c = X2DIGITS_TO_NUM (h[1], h[2]);

論壇徽章:
0
90 [報告]
發(fā)表于 2011-10-02 19:46 |只看該作者
回復 89# wangzhen11aaa
不會陷入死循環(huán),因為是在if語句中,編譯成匯編時在if模塊里是不會跳轉到else語句中的。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP