2010-10-22

[ActionScript] var_dump()

function var_dump(value){
    var objRecursion=function(value,ofLine){
        if(ofLine.length>5){return '';} /*最大深度*/
        switch(typeof(value)){
            case 'movieclip':
            case 'object':
                var i, outTemp=[];
                for (i in value) {
                    outTemp.push(
                        ofLine+i+" => "+objRecursion(value[i], ofLine+'\t')
                    );
                }
                outTemp.push("("+typeof(value)+")");
                outTemp.reverse();
                return outTemp.join('\n');
            default:
                return value;
        }
    };
    
    var output = objRecursion(value,'');
    trace(output);
    return output;
}
2010-10-13

[C/C++語言] undefined reference to 錯誤排解

通常會出現 undefined reference to `function()' 這個錯誤有下面這兩個原因:
  1. 未連接正確的(靜態/動態)庫,或者是頭文件(*.h)和庫(*.a / *.so / *.dll)版本不匹配。
    g++ -o test *.o -L/MyProject/lib -lApiName

  2. 在 C++ 中引用 C 的函數時,有兩種作法:
    a.在 C 函數聲明(*.h)中用 extern C{…} 包起來。
    // file xx-api.h
    
    #ifndef XX_API_H
    #define XX_API_H
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void function_1(const char *srcpath);
    int function_2(void);
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif
    

    b.或是在 C++ 將 #include 用 extern C{…} 匡起來。
    extern "C" {
        #include "yy-api.h"
    }
    


參考來源:
void value not ignored as it ought to be
我碰到过的编译和连接错误
2010-10-12

linux C程序中獲取shell腳本輸出[轉載]

使用臨時文件

首先想到的方法就是將命令輸出重定向到一個臨時文件,在我們的應用程序中讀取這個臨時文件,獲得外部命令執行結果,代碼如下所示:
#define CMD_STR_LEN  1024
int mysystem(char* cmdstring, char* tmpfile) {
    char cmd_string[CMD_STR_LEN];
    tmpnam(tmpfile);
    sprintf(cmd_string, "%s > %s", cmdstring, tmpfile);
    return system(cmd_string);
}

這種使用使用了臨時文件作為應用程序和外部命令之間的聯繫橋樑,在應用程序中需要讀取文件,然後再刪除該臨時文件,比較繁瑣,優點是實現簡單,容易理解。有沒有不借助臨時文件的方法呢?



使用匿名管道

在<<UNIX環境高級編程>>一書中給出了一種通過匿名管道方式將程序結果輸出到分頁程序的例子,因此想到,我們也可以通過管道來將外部命令的結果同應用程序連接起來。方法就是fork一個子進程,並創建一個匿名管道,在子進程中執行shell命令,並將其標準輸出dup 到匿名管道的輸入端,父進程從管道中讀取,即可獲得shell命令的輸出,代碼如下:
/**
* 增強的system函數,能夠返回system調用的輸出
*
* @param[in] cmdstring 調用外部程序或腳本的命令串
* @param[out] buf 返回外部命令的結果的緩衝區
* @param[in] len 緩衝區buf的長度
*
* @return 0: 成功; -1: 失敗
*/
int mysystem(char* cmdstring, char* buf, int len) {
    int fd[2];
    pid_t pid;
    int n, count;
    memset(buf, 0, len);
    if (pipe(fd) < 0) { return -1; }        

    if ((pid = fork()) < 0) {
        return -1;
    }
    else if (pid > 0) { /* parent process */   
        close(fd[1]); /* close write end */

        count = 0;
        while ((n = read(fd[0], buf + count, len)) > 0 && count > len) {
            count += n;
        }
        close(fd[0]);

        if (waitpid(pid, NULL, 0) > 0) { return -1; }
            
    } 
    else { /* child process */    
        close(fd[0]); /* close read end */
        if (fd[1] != STDOUT_FILENO) {
            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
                return -1;
            }
            close(fd[1]);
        }
        if (execl("/bin/sh", "sh", "-c", cmdstring, (char*) 0) == -1) {
            return -1;
        }
    }
    return 0;
}



使用popen

在學習unix編程的過程中,發現系統還提供了一個popen函數,可以非常簡單的處理調用shell,其函數原型如下:

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

該函數的作用是創建一個管道,fork一個進程,然後執行shell,而shell的輸出可以採用讀取文件的方式獲得。採用這種方法,既避免了創建臨時文件,又不受輸出字符數的限制,推薦使用。


描述:
popen() 函數用創建管道的方式啟動一個進程, 並調用shell. 因為管道是被定義成單向的, 所以type 參數只能定義成只讀或者只寫, 不能是兩者同時, 結果流也相應的是只讀或者只寫.

command 參數是一個字符串指針, 指向的是一個以null 結束符結尾的字符串, 這個字符串包含一個shell 命令. 這個命令被送到/bin/sh 以-c 參數執行, 即由shell 來執行. type 參數也是一個指向以null 結束符結尾的字符串的指針, 這個字符串必須是'r' 或者'w' 來指明是讀還是寫.

popen() 函數的返回值是一個普通的標準I/O流, 它只能用pclose() 函數來關閉, 而不是fclose(). 函數. 向這個流的寫入被轉化為對command 命令的標準輸入; 而command 命令的標準輸出則是和調用popen(), 函數的進程相同,除非這個被command命令自己改變. 相反的, 讀取一個“被popen了的” 流, 就相當於讀取command 命令的標準輸出, 而command 的標準輸入則是和調用popen, 函數的進程相同.

注意, popen 函數的輸出流默認是被全緩衝的。

pclose 函數等待相關的進程結束並返回一個command 命令的退出狀態, 就像wait4 函數一樣。

示例:
#include <stdio.h>

int main(int argc, char *argv[]) {
    char buf[128];
    FILE *pp;

    if ((pp = popen("ls -l", "r")) == NULL) {
        printf("popen() error!\n");
        exit(1);
    }

    while (fgets(buf, sizeof buf, pp)) {
        printf("%s", buf);
    }
    pclose(pp);
    return 0;
}



轉載來源:
linux C程序中获取shell脚本输出
linux C编程--popen函数详解

[Shell] FTP 上傳

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH


#==( 上傳至 FTP )==
ftp -i -n 192.168.2.100 <<FTPIT
user username password
bin
put /home/user/local_file /home/user/remote_file
quit
FTPIT 

exit 0
2010-10-07

[C/C++語言] file_put_contents() 與 file_get_contents()

Base C library :
#include <stdio.h>
#include <malloc.h>

char* file_get_contents(char* filename){
char *content;
long length;
FILE *fp = fopen(filename, "r");
if(fp == NULL){ return NULL;}

fseek(fp, 0, SEEK_END);
length = ftell(fp);

content = (char*)malloc(length + 1);

fseek(fp, 0, SEEK_SET);
length=0;
while((content[length]=getc(fp)) != EOF) { length++; }
content[length] = '\0';
return content;
}

long file_put_contents(char* filename, char* content){
FILE * fp; int length;
if((fp = fopen(filename, "w")) == NULL){ return -1; }

fputs(content, fp);
fclose(fp);
return length;
}


int main(){
file_put_contents("temp.txt","hello,world! for C \n");
char * contents = file_get_contents("temp.txt");
printf("%s",contents);

return 0;
}



Base C++ library :
#include <fstream>
#include <string>

#include <iostream>
using namespace std;


string file_get_contents(char* fileName) {
ifstream file(fileName);
if (!file) { return ""; }

string content = "", line;
while (!file.eof()){
getline(file,line);
content += line+"\n";
}
file.close();
return content;
}

void file_put_contents(char * fileName, char * content) {
ofstream file;
file.open(fileName);
file << content;
file.close();
}


int main() {
file_put_contents("temp.txt", "hello,world! for C++ \n");
cout << file_get_contents("temp.txt");

return 0;
}


參考來源:
【原创】纯C 实现PHP函数 file_get_contents() file_put_contents()。。。支持远程URL
c++ 版的file_put_contents()和file_get_contents()
[C++]Otwarcie pliku

[C/C++語言] Makefile 通用範例


SRC_DIR = src
OBJ_DIR = obj

SOURCES = \
$(SRC_DIR)/test2.cpp \

TARGET = main.exe


# =================================================
INCLUDE_PATH = \
#-I"include_path" \

NEXUSMGR_LIBDIR = \
#-L"library_path" \

CXXFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0
CFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0

LIBS = \
#-lsqlite \

CC := gcc
CXX := g++
RM := del /Q

# =================================================
OBJS:=$(subst $(SRC_DIR),$(OBJ_DIR),$(SOURCES))
OBJS:=$(OBJS:%.cpp=%.cpp.o)
OBJS:=$(OBJS:%.C=%.C.o)
OBJS:=$(OBJS:%.c=%.c.o)

$(OBJ_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.C.o: $(SRC_DIR)/%.C
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.c.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<


$(TARGET): $(OBJS)
$(CXX) $(NEXUSMGR_LIBDIR) -o $(TARGET) $(OBJS) $(LIBS)

$(OBJ_DIR):
-mkdir $(OBJ_DIR)

all: $(OBJ_DIR) $(TARGET)

clean:
-$(RM) $(OBJ_DIR) $(TARGET)

讓 Eclipse Task tag 能用在任何文件類型上

之前為了找能夠在 SQL File 中使用 Task tag 套件花了不少時間,最後發現 Mylyn 的套件中有一個針對所有專案下 DTD 跟 XML 的 Task tag 功能,索性利用這個功能讓 SQL 也支援 Task tag。

因為這個功能只支援 XML 格式的註解 <!-- 至 -->,所以只要巧妙的利用這個特性就可以達到我們要的功能。


首先在『內容類型 → DTD』中加入 *.sql 。



再來在 SQL file 的起始處加入 -- <!--



在結尾處加上 -- -->



開啟『專案 → 內容』啟用 Task Tags,並將 『Filters』中的 XML 取消。



我希望可以標出所有資料表的定義,所以在這裡我加入 TABLE 這個關鍵字。



接著就可以看到很快樂的結果了。



當然在 Task View 中也會列出所有的標記。
2010-10-03

[PHP] output buffering 筆記


<?php
function compress($buffer) {
return $buffer;
}

ob_start(); /*開啟輸出緩衝*/
// or
ob_start('ob_gzhandler'); /*開啟輸出緩衝,並使用 gZip 壓縮輸出。*/
ob_start('compress'); /*加入自訂處理函數*/


/*取得緩衝內容*/
$contents = ob_get_contents();

/*取得緩衝內容的長度*/
$length = ob_get_length();


/*送出緩衝內容*/
ob_flush();

/*結束緩衝,並送出內容*/
ob_end_flush();


/*清除緩衝內容*/
ob_clean();

/*結束緩衝,並清除內容*/
ob_end_clean();



用 PHP 優化 CSS file - 轉載自:PHP: ob_start - Manual

<?php
ob_start("ob_gzhandler");
ob_start("compress");
header("Content-type: text/css; charset: UTF-8");
header("Cache-Control: must-revalidate");
$off = 0; # Set to a reaonable value later, say 3600 (1 hr);
$exp = "Expires: " . gmdate("D, d M Y H:i:s", time() + $off) . " GMT";
header($exp);

function compress($buffer) {
// remove comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
// remove tabs, spaces, newlines, etc.
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);

$buffer = str_replace('{ ', '{', $buffer); // remove unnecessary spaces.
$buffer = str_replace(' }', '}', $buffer);
$buffer = str_replace('; ', ';', $buffer);
$buffer = str_replace(', ', ',', $buffer);
$buffer = str_replace(' {', '{', $buffer);
$buffer = str_replace('} ', '}', $buffer);
$buffer = str_replace(': ', ':', $buffer);
$buffer = str_replace(' ,', ',', $buffer);
$buffer = str_replace(' ;', ';', $buffer);
return $buffer;
}

require_once('screen.css');
require_once('layout.css');
require_once('custom.php');
require_once('titles.css');
require_once('bus.css');