学习sed源码第三天之malloc和异常处理

学习sed源码第三天之malloc和错误处理

今天继续重写sed源码,

1.  ck_malloc

处理malloc失败,简单的

2. panic 

简单的错误处理, APUE中已经有差不多代码


总之第三天是个轻松天


添加了utils.c文件,在想是不是该写Makefile了,等等把。

/**
 *  jeff学习sed源码练习
 *
 *
 *  file: sed.c 
 *  created: jeff
 *  date: 2013.1.23
 *
 *      modified by: jeff
 *      reason     : 增加STDC_HEADERS判断和__STDC__判断 
 *      date       : 2013.1.24
 *
 *      modified by: jeff
 *      reason     : 增加e选项处理和usage
 *      date       : 2013.1.25
 *  
 ********************************************************************/

/**
 *__STDC__("standard c")宏可以被用来将代码分割为ANSI和K&R部分。
  __STDC__ 被定义并是1,表示支持ANSI C
 */

#if __STDC__
#define VOID void
#else
#define VOID char
#endif
/***
 * _GNU_SOURCE :  使用GNU库
 *
 */
#define _GNU_SOURCE

#ifndef isblank
#define isblank(c) ((c) == ' '|| (c) == '\t')
#endif

#include <stdio.h>
#include <getopt.h>
/**
 * ANSI C标准头文件和定义使用
 */
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
/**
 * 这段就很明显了,如果定义了STDC_HEADERS(C 标准的)
 * 那么就使用string.h 
 * 如果定义了HAVE_STRING_H使用string.h和memory.h ,因为一些定义会混在两个头文件中
 *
 * 如果没有STDC_HEADERS或者HAVE_STRING_H
 * 只能使用 strings.h
 *
 * strings.h 和 string.h的区别: string.h是标准C库,strings.h来自BSD系统
 *
 * 可移植三种环境:
 *  1. 有标准C 库
 *  2. 有string.h 但一些定义在memory.h 
 *  3. 有strings.h
 *
 */

#if HAVE_STRING_H || defined(STDC_HEADERS)
#include <string.h>
#if !defined(STDC_HEADERS)
#include <memory.h>
#endif
#else
#include <strings.h>
#endif

extern char *myname;

char *version_string="GNU sed version 1.18";
int no_default_output = 0;


void usage (int status);

static struct option longopts[]=
{
    {"expression", 1, NULL, 'e'},
    {"file", 1, NULL, 'f'},
    {"quiet", 0, NULL, 'n'},
    {"silent", 0, NULL, 'n'},
    {"version", 0, NULL, 'V'},
    {"help", 0, NULL, 'h'},
    {NULL, 0, NULL, 0}
};

int
main (int argc, char** argv)
{
    int opt;
    char* e_strings = NULL;
    int compiled= 0;
    

    myname=argv[0];
    /**
     *
     *获取参数, getopt_long
     *
     *int getopt_long(int argc, char * const argv[],
      const char *optstring,
      const struct option *longopts, int *longindex);
     *
     * argc 来自main
     * argv 来自main
     * optstring: 可选项 hn 是无参数, ef是有参数并且可以紧跟也可以有空格隔开,V选项也是无参数
     * struct option {
     *          
     *  const char *name; 长选项名称
     *          
     *  int has_arg; 是否有参数, 0,1,2 无参,有参,可选
     *          
     *  int *flag; NULL
     *          
     *  int val; short char
     *          
     *};
     *
     */

    while( (opt =getopt_long (argc, argv, "hne:f:V", longopts, (int*)0))!= EOF)
    {
        switch(opt)
        {
          case 'n':     no_default_output = 1;
                        break;
          case 'e':
                        if(e_strings = NULL)
                        {
                           e_strings =ck_malloc(strlen(optarg)+2);
                           strcpy(e_strings, optarg);
                        }
                        else
                        {
                          
                        }
                        break;
          case 'f':
                        break;
          case 'V':     
                        fprintf(stderr, "%s\n", version_string);
                        break;              
          case 'h':     usage(0);
                        break;
          default:
                        break;
        }
    
    }
        
    exit(0);
}


void usage (int status)
{
    fprintf(status ? stderr : stdout, "\
 Usage: %s [-nV] [--quiet] [--silent] [--version] [-e script]\n\
        [-f script-file] [--expression=sript] [--file=script-file] [file...]\n",
        myname);
    exit (status);
}

 
/**
 *  filename: utils.c 
 *
 *  created by jeff
 *  date:   2013.1.25
 *  reason: first version
 *
 ***********************************************************/

#if __STDC__
#define VOID void
#else
#define VOID char
#endif

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>

VOID *ck_malloc(int size);
VOID panic(char*, ...);
char* myname;
/**
 *  malloc 失败处理
 *
 */

VOID *ck_malloc(int size)
{
    VOID *ret;

    if(!size)
      size++;

    ret=malloc(size);
    if(ret ==(VOID*)0)
        panic("Couldnot allocate memory");
    
    return ret;
}

/**
 *  错误处理代码
 *  
 */
void panic(char* str, ... )
{
    va_list ap;

    fprintf(stderr, "%s: ", myname);
    va_start(ap, str);
    vfprintf(stderr, str, ap); 
    va_end(ap);
    putc('\n', stderr);
    exit(4);
}