学习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); }