Feed on
Posts
Comments

[CodeIgniter] 利用 jQuery 簡易驗證使用者帳號/Email

推到 Twitter!
推到 Plurk!
推到 Facebook!
codeigniter_2

好久沒寫相關 CodeIgniter 文章,針對於剛入門 CI 的新手們,此篇教學如何使用 jQuery AJAX 搭配 CI 來驗證使用者帳號及相關資訊,本篇教學帶您如何在 CI 中發出 AJAX request 給伺服器端。

請先在網頁 header 自行 include jQuery 檔案,或者可以使用 Google AJAX CDN 方式來讀取,將底下程式碼放到 之前:

$(document).ready(function() {
    /* 先停止讀取狀態 */
    $('#Loading').hide();

    /* 填寫好 email 欄位,按下 Tab 會進行讀取 */
    $('#email').blur(function(){
    /* 讀取 email 欄位 */
    var a = $("#email").val();
    /* email 正規語法 */
    var filter = /^[a-zA-Z0-9]+[a-zA-Z0-9_.-]+[a-zA-Z0-9_-]+@[a-zA-Z0-9]+[a-zA-Z0-9.-]+[a-zA-Z0-9]+.[a-z]{2,4}$/;
    /* 簡易驗證 email */
    if(filter.test(a)){
        /* 讀取狀態 */
        $('#Loading').show();
        /* AJAX 比對資料庫 */
        $.post("<?php echo base_url()?>controller_name/check_email_availablity", {
            email: $('#email').val()
        }, function(response){
            /* 驗證後讀取 reponse 狀態 */
            $('#Loading').hide();
            setTimeout("finishAjax('Loading', '"+escape(response)+"')", 400);
        });
        return false;
    }
});

Continue Reading »

[Vim] 將 Tab 轉換成 Space

推到 Twitter!
推到 Plurk!
推到 Facebook!

Update 2010.08.28: Pspad 轉換既有 Tabs to Spaces by bootleq
vim_header
為了統一 Windows 跟 Linux 底下的編輯器在使用 Tab 功能相同,所以調整了 VimPspad(我常用編輯器)的設定,底下是針對 Vim 及 Pspad 的解決方法。首先當大家使用 Vim 編輯器撰寫程式,常常會使用 Tab 來縮排程式碼,我們可以使用 expandtab 來插入空白鍵(Space)取代 Tab:

:set expandtab

控制插入 Tab 時所需要的空白鍵(Tab)字元數,例如用4個空白鍵取代 Tab:

:set tabstop=4

在我們設定完 expandtab 之後,所有的 Tab 鍵將會被 Space 所取代,但是原本在檔案文件中的 Tab 將不會改變,為了取代原有的 Tab 到新的設定,我們必須鍵入:

:retab

針對程式縮排所需要的 Space 個數,我們可以使用 shiftwidth 選項

:set shiftwidth=4

底下舉個例子:

  • 將文件中 Tab 取代成 Space
  • 所有 Tab 用4個 Space 取代
:set tabstop=4
:set shiftwidth=4
:set expandtab

Pspad 設定

Settings -> Programing Settings -> Editor (Part 2)
設定:
Tab Width:4
Indent Width:4
請勿勾選 Real Tab
如果要把既有的 Tab 轉換成 Space,可以使用:
編輯特殊轉換將 Tab 轉成空白
Edit->Special conversion->Convert Tabs to Spaces

Pspad
針對 Makefile 需要使用 Tab,我們必須在 .vimrc 裡面在加入底下:

autocmd FileType make setlocal noexpandtab

Ref:
Converting tabs to spaces

Html5 模板架構(Boilerplate)

推到 Twitter!
推到 Plurk!
推到 Facebook!

HTML5 Boilerplate - A rock-solid default for HTML5 awesome._1282574693481
今年在 COSCUP 大會上最主流的議題就是 Html5,今天看到一個網站 HTML5 Boilerplate,這網站提一個全新 html 5 模板,自從離開 Dreamweaver 樣板軟體,利用 Pspad 手動撰寫 html,此網站就發揮非常大的用處,提供全新 html,CSS 以及 javascript,支援了底下很多功能:

  • 跨瀏覽器 (IE6…)
  • 支援多種 html5 Tag
  • Compress 和 cache html 檔案
  • CSS IE6 , IE7 Hack
  • IE6 Png Fix (連這個都幫忙解決了)
  • 支援 CDN jQuery,避免在 local 端沒讀取到檔案

你還可以根據自己需要的功能做添加或者是減少,CSS reset、跨瀏覽器 CSS、robots.txt、Apache .htaccess cache 壓縮也有支援,如果不需要的功能,也可以參考看看,對於初學者也是非常好的學習例子。

Git 版本控制:利用 git reset 恢復檔案、暫存狀態、commit 訊息

推到 Twitter!
推到 Plurk!
推到 Facebook!

這次來介紹一下 git reset 的用法,為什麼會介紹這指令呢?因為今天想要看專案狀態,用 git status 觀看,發現被我玩爛了,所以出現了底下錯誤訊息:

$ git status
error: bad index file sha1 signature
fatal: index file corrupt

解決此問題非常簡單,要先刪除 index 檔案,請先砍掉 .git/index,恢復此 index 請用

git reset

這行指令相當於 git reset –mixed HEAD,或者是可以用 git read-tree 來取代 git reset,當然 git reset 不只是有這功能而已,假如您已經建立了 commit 訊息,也可以將此訊息拿掉,重新在 commit,或者是您修改過的檔案在暫存區,git 也可以幫您恢復到未暫存,或者是不想要這次的修改,也可以恢復到未修改的檔案喔。

取消已經暫存的檔案

假如我們有兩個檔案需要 commit,但是不小心按到 git add * 全部加入到暫存區,那該怎麼恢復呢?

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   Makefile
#       modified:   user/easy_setup/easysetup.h
#

上面是以經在暫存區裡面等待被 commit 檔案(Changes to be committed),大家可以看到括號裡面有提示如何拿掉 (use “git reset HEAD …” to unstage),所以我們下:

git reset HEAD user/easy_setup/easysetup.h

之後會看到 『user/easy_setup/easysetup.h: locally modified』此訊息,這時候在用 git status 看狀態

# On branch master
# Changes to be committed:
#   (use "git reset HEAD </file><file>..." to unstage)
#
#       modified:   Makefile
#
# Changed but not updated:
#   (use "git add </file><file>..." to update what will be committed)
#
#       modified:   user/easy_setup/easysetup.h
#

Continue Reading »

Git 版本控制: 「You have some suspicious patch lines」

推到 Twitter!
推到 Plurk!
推到 Facebook!

相信大家對 Git 並不陌生,這次在升級 Moztw討論區,從 3.0.5 升級到 3.0.7 p1,過程由其他 Moztw 成員升級,我在將最後程式 commit 到 github,因為兩個版本差異性很大,所以有新增多個檔案,commit 過程出現了錯誤訊息:「You have some suspicious patch lines」,這是因為 git 會檢查每行程式碼最後是否有多餘空白或者是 Tab 按鍵,為瞭解決此問題,可以去修改 .git/hooks/pre-commit,將底下程式碼:

if (s/^\+//) {
    $lineno++;
    chomp;
    if (/\s$/) {
        bad_line("trailing whitespace", $_);
    }
    if (/^\s* \t/) {
        bad_line("indent SP followed by a TAB", $_);
    }
    if (/^([<>])\1{6} |^={7}$/) {
        bad_line("unresolved merge conflict", $_);
    }
}

改成:

if (s/^\+//) {
    $lineno++;
    chomp;
#   if (/\s$/) {
#       bad_line("trailing whitespace", $_);
#   }
#   if (/^\s* \t/) {
#       bad_line("indent SP followed by a TAB", $_);
#   }
    if (/^([<>])\1{6} |^={7}$/) {
        bad_line("unresolved merge conflict", $_);
    }
}

暫時停止 git 過濾字串,等 commit 完成之後,在將其 unmask 掉。

參考網站:
Git on Windows: 「You have some suspicious patch lines」

[C/C++] cstring (string.h) 函式:strcat, strncat, strcmp, strncmp

推到 Twitter!
推到 Plurk!
推到 Facebook!

串接函式 strcat

strcat 此函式用來連接兩字串合併成單一字串,直接看底下範例:

/* strcat example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[80];
  strcpy (str,"these ");
  strcat (str,"strings ");
  strcat (str,"are ");
  strcat (str,"concatenated.");
  puts (str);
  return 0;
}

output:

these strings are concatenated.

看一下 strcat 原始碼:

char *
strcat(char * __restrict s, const char * __restrict append)
{
    char *save = s;

    for (; *s; ++s);
    while ((*s++ = *append++));
    return(save);
}

設定指標 save 成 source,再將 s 指標指向最後,接下來根據 append 字串一個一個往後串接,直到碰到 \0 終止 while 迴圈,最後在將指標 *save 回傳即可。

比較函式 strcmp

strcmp 用來比較兩字串是否相同,相同回傳 0,不相同則回傳兩字串 ASCII 相減的值。底下範例:

/* strcmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char szKey[] = "apple";
  char szInput[80];
  do {
     printf ("Guess my favourite fruit? ");
     gets (szInput);
  } while (strcmp (szKey,szInput) != 0);
  puts ("Correct answer!");
  return 0;
}

來看看 strcmp 原始碼

#include <string.h>

/*
 * Compare strings.
 */

int
strcmp(s1, s2)
    const char *s1, *s2;
{
    while (*s1 == *s2++)
        if (*s1++ == 0)
            return (0);
    return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}

大家可以看到,比對字串會依序比對,直到 s1 最後字元 \0 則會回傳 0 代表比對成功,如果中途有字元比對不同,則會將兩個字元相減回傳。

串接函式 strncat

strncat 用來串接指定多少字元,底下範例:

/* strncat example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str1[20];
  char str2[20];
  strcpy (str1,"To be ");
  strcpy (str2,"or not to be");
  strncat (str1, str2, 6);
  printf("%s\n", str1);
  return 0;
}

strncat 原始碼

#include <string.h>

/*
 * Concatenate src on the end of dst.  At most strlen(dst)+n+1 bytes
 * are written at dst (at most n+1 bytes being appended).  Return dst.
 */

char *
strncat(char * __restrict dst, const char * __restrict src, size_t n)
{
    if (n != 0) {
        char *d = dst;
        const char *s = src;

        while (*d != 0)
            d++;
        do {
            if ((*d = *s++) == 0)
                break;
            d++;
        } while (--n != 0);
        *d = 0;
    }
    return (dst);
}

一樣是先將 dst 指標指向最後一個字元+1,再根據需要串接的大小來決定 dst 最後的指標。

比較函式 strncmp

直接看範例,比較字串前兩個字元是否相同,如果相同則印出

/* strncmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
  int n;
  puts ("Looking for R2 astromech droids...");
  for (n=0 ; n<3 ; n++)
    if (strncmp (str[n],"R2xx",2) == 0)
    {
      printf ("found %s\n",str[n]);
    }
  return 0;
}

strncmp 原始碼

#include <string.h>

int
strncmp(s1, s2, n)
    const char *s1, *s2;
    size_t n;
{

    if (n == 0)
        return (0);
    do {
        if (*s1 != *s2++)
            return (*(const unsigned char *)s1 -
                *(const unsigned char *)(s2 - 1));
        if (*s1++ == 0)
            break;
    } while (--n != 0);
    return (0);
}

最後參數傳入 0 則會直接回傳 0,依序比對,直到 n =0 的時候跳出比較迴圈,然後回傳 0,代表比對成功。

[C/C++] cstring (string.h) 搜尋函式:strstr, strchr

推到 Twitter!
推到 Plurk!
推到 Facebook!

strstr

這次介紹 C 語言常用 string 函式:strstr,主要是針對兩個輸入參數做比對,Parameters 1輸入字串Parameters 2找尋字串,strstr 會先將頭一次比對成功的 pointer 回傳,也就是如果要找尋 appleboyappleboy 字串中的 boy,函式會回傳第一次比對成功的 boy pointer,而並非回傳最後一個比對到的,底下是一個參考範例:

/* strstr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This is a simple string";
  char * pch;
  /* 找尋 simple 字串 */
  pch = strstr (str,"simple");
  /* 將 simple 換成 sample */
  strncpy (pch,"sample",6);
  puts (str);
  return 0;
}

看一下 Kernel 原始檔案,strstr 函式:

/*
 * Find the first occurrence of find in s.
 */

char *
strstr(s, find)
    const char *s, *find;
{
    char c, sc;
    size_t len;

    if ((c = *find++) != 0) {
        len = strlen(find);
        do {
            do {
                if ((sc = *s++) == 0)
                    return (NULL);
            } while (sc != c);
        } while (strncmp(s, find, len) != 0);
        s--;
    }
    return ((char *)s);
}

先將 sc 指定為內容字串,c 指定為找尋字串,利用兩個迴圈開始一一筆對,利用 strncmp 比對字串,在將比對成功的 pointer 回傳,但是回傳之前需要在將 s– 回到前一個指標,這樣就ok了。

strchr

這字串用來找尋第一次比對成功單一字母符號,也是一樣回傳該指標,底下是範例:

/* strchr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "This is a sample string";
  char * pch;
  printf ("Looking for the 's' character in \"%s\"...\n",str);
  pch=strchr(str,'s');
  while (pch!=NULL)
  {
    printf ("found at %d\n",pch-str+1);
    pch=strchr(pch+1,'s');
  }
  return 0;
}

上面範例很容易,那底下來看看完整 strchr 程式碼:

char * strchr
(const char *p, int ch)
{
    char c;

    c = ch;
    for (;; ++p) {
        if (*p == c)
            return ((char *)p);
        if (*p == '\0')
            return (NULL);
    }
    /* NOTREACHED */
}

就只能針對單一字母符號做搜尋,跟 strstr 不同的是 strstr 是針對多個字母符號搜尋,很好區別吧 ^^。

[網站] 好站連結 (七) Android, javascript, Css, PHP, Perl, FreeBSD, Linux

推到 Twitter!
推到 Plurk!
推到 Facebook!

Windows C#

html

apache

javascript

CSS

php

MySQL

Perl

FreeBSD

MSSQL

Android

Linux

C/C++

Network

[PHP] GoEz Framework

[Kernel Driver] 撰寫簡易 Timer 機制

推到 Twitter!
推到 Plurk!
推到 Facebook!

在底層 Linux Kernel 提供了時序(timing)機制,方便驅動程式設計者所使用,核心是依據硬體發出的『計時器中斷』來追蹤時間的流動狀況。我們可以依據 HZ 的值來設計 Delay 機制,讓驅動程式可以每隔固定一段時間啟動或者是發出訊號,也可以利用 Timer 來讓 LED 閃爍變化,在介紹 Timer API 之前,可以先參考 Linux Kernel: 簡介HZ, tick and jiffies 這篇文章,瞭解一些相關名詞,舉例:如果想知道一秒後的 jiffies 時間,可以寫成底下:

#ifdef CONFIG_BMA150_TIMER
#include <linux/timer.h>
#endif
j = jiffies;
/* 一秒之後 */
stamp_1 = j + HZ;
/* 半秒之後 */
stamp_1 = j + HZ/2;
/* 20秒之後 */
stamp_1 = j + 20*HZ;

Timer API 用法

筆記一下自己在寫 BOSCH Sensortec 三軸加速偵測器(BMA150 Sensor) Driver 的時候,遇到底層要回報 input event X,Y,Z 到 Android HAL(Hardware abstraction layer),所以利用 Timer 的機制定時 report 給 Android。

首先宣告:

#ifdef CONFIG_BMA150_TIMER
#include <linux/timer.h>
#endif
/* 定義 timer_list struct */
#ifdef CONFIG_BMA150_TIMER
struct timer_list bma150_report_timer;
#endif

在 Driver 內的 bma150_probe 裡面 call function:

#ifdef CONFIG_BMA150_TIMER
  bma150_init_timer();
#endif

撰寫 bma150_init_timer 函式:

#ifdef CONFIG_BMA150_TIMER
static void bma150_init_timer(void)
{  
  D("BMA150 init_timer start\n");
  /* Timer 初始化 */
  init_timer(&bma150_report_timer);
  /* 定義 timer 所執行之函式 */
  bma150_report_timer.function = bma150_report;
  /* 定義 timer 傳入函式之 Data */
  bma150_report_timer.data = ((unsigned long) 0);
  /* 定義 timer Delay 時間 */
  bma150_report_timer.expires = jiffies + BMA150_REPORT_DELAY_1;
  /* 啟動 Timer*/
  add_timer(&bma150_report_timer);
}
#endif

上述 add_timer 執行之後,會在一秒後執行 bma150_report 函式,執行之後就會停止,所以如果要一直產生迴圈,就必須在 bma150_report 裡面繼續加入 add_timer,改寫如下:

static int bma150_report(void)
{
  D("appleboy: test timer. \n");
#ifdef CONFIG_BMA150_TIMER
  bma150_report_timer.expires = jiffies + BMA150_REPORT_DELAY_2;
  add_timer(&bma150_report_timer);
#endif
  return 0;
}

我們可以重新定義 expires 時間 jiffies + BMA150_REPORT_DELAY_2,就可以一直循環了,要離開 Timer 可以在最後加入 deltimer(&bma150_report_timer),最後就完成簡易的 Timer 功能。

參考:
add_timer的使用方法
Linux Kernel: 簡介HZ, tick and jiffies

[Linux Kernel] 簡單 hello world: License and Module 介紹(part 3)

推到 Twitter!
推到 Plurk!
推到 Facebook!

在 Kernel 2.4 或以上版本,在編譯模組完成,要進行 load module 之前,你會發現底下訊息:

# insmod hello-3.o
Warning: loading hello-3.o will taint the kernel: no license
  See http://www.tux.org/lkml/#export-tainted for information about tainted modules

很顯然這訊息是要您在 kernel module 裡面加上版權宣告,例如:”GPL”,”GPL v2″…等來宣告您的 module 並非 open source,利用 MODULE_LICENSE() 巨集來宣告程式 License,同樣的,可以用 MODULE_DESCRIPTION() 來描述此模組或者是 Driver 的功用跟簡介,以及用 MODULE_AUTHOR() 來定義此模組作者,這些巨集都可以在 linux/module.h 裡找到,但是這些並非用於 Kernel 本身,如果大家想看範例程式,可以到 drivers/ 資料夾底下觀看每一個 Driver 程式,底下是簡單 hello world 範例:

#include <linux/kernel.h> /* pr_info所需 include 檔案*/
#include <linux/init.h>
#include <linux/module.h> /* 所有 module 巨集需要檔案*/
#include <linux/version.h>

static int __init hello_init(void)
{
    pr_info("Hello, world appleboy\n");
    pr_info("The process is \"%s\" (pid %i)\n", current->comm, current->pid);
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye\n");
}
MODULE_DESCRIPTION("Hello World !!");/* 此程式介紹與描述*/
MODULE_AUTHOR("Bo-Yi Wu <appleboy.tw AT gmail.com>");/* 此程式作者*/
MODULE_LICENSE("GPL");/* 程式 License*/
module_init(hello_init);
module_exit(hello_exit);

在 linux/module.h 裡頭,可以找到 MODULE_LICENSE 可定義的 License

/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *  "GPL"               [GNU Public License v2 or later]
 *  "GPL v2"            [GNU Public License v2]
 *  "GPL and additional rights" [GNU Public License v2 rights and more]
 *  "Dual BSD/GPL"          [GNU Public License v2
 *                   or BSD license choice]
 *  "Dual MIT/GPL"          [GNU Public License v2
 *                   or MIT license choice]
 *  "Dual MPL/GPL"          [GNU Public License v2
 *                   or Mozilla license choice]
 *
 * The following other idents are available
 *
 *  "Proprietary"           [Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.   So modinfo can show license info for users wanting to vet their setup
 *  is free
 * 2.   So the community can ignore bug reports including proprietary modules
 * 3.   So vendors can do likewise based on their own policies
 */

巨集 define:

#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)

/*
 * Author(s), use "Name <email>" or just "Name", for multiple
 * authors use multiple MODULE_AUTHOR() statements/lines.
 */

#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)

/* What your module does. */
#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)

 Page 1 of 44  1  2  3  4  5 » ...  Last »