1. /********************************************************************
  2. * Android development tools line_endings hacking
  3. * 说明:
  4. * 本文主要是对android源代码中的line_endings开发工具进行了解读,
  5. * 目的是为了知道传说中的dos,unix文件之间转换的工作机制。
  6. *
  7. * 2016-5-3 深圳 南山平山村 曾剑锋
  8. *******************************************************************/
  9.  
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <sys/stat.h>
  16.  
  17. #define BUFSIZE (1024*8)
  18. static void to_unix(char* buf);
  19. static void unix_to_dos(char* buf2, const char* buf);
  20.  
  21. // 使用方法
  22. int usage()
  23. {
  24. fprintf(stderr, "usage: line_endings unix|dos FILES\n"
  25. "\n"
  26. "Convert FILES to either unix or dos line endings.\n");
  27. return ;
  28. }
  29.  
  30. // 定义Node数据结构
  31. typedef struct Node {
  32. struct Node *next;
  33. char buf[BUFSIZE*+];
  34. } Node;
  35.  
  36. int
  37. main(int argc, char** argv)
  38. {
  39. // 枚举UNIX,DOS两种数据
  40. enum { UNIX, DOS } ending;
  41. int i;
  42.  
  43. // 参数个数判断
  44. if (argc < ) {
  45. return usage();
  46. }
  47.  
  48. // 参数比较
  49. if ( == strcmp("unix", argv[])) {
  50. ending = UNIX;
  51. }
  52. else if ( == strcmp("dos", argv[])) {
  53. ending = DOS;
  54. }
  55. else {
  56. return usage();
  57. }
  58.  
  59. // 命令行传入的参数可能有多个,利用for循环进行轮流转换。
  60. for (i=; i<argc; i++) {
  61. int fd;
  62. int len;
  63.  
  64. // force implied
  65. chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
  66.  
  67. // 打开文件
  68. fd = open(argv[i], O_RDWR);
  69. if (fd < ) {
  70. fprintf(stderr, "unable to open file for read/write: %s\n", argv[i]);
  71. return ;
  72. }
  73.  
  74. // 获取文件大小
  75. len = lseek(fd, , SEEK_END);
  76. lseek(fd, , SEEK_SET);
  77.  
  78. // 文件长度正常才有必要进行转换
  79. if (len > ) {
  80. // 创建根节点
  81. Node* root = malloc(sizeof(Node));
  82. Node* node = root;
  83. node->buf[] = ; // root节点的buf数据位0
  84.  
  85. while (len > ) {
  86. // 创建节点,并出示节点
  87. node->next = malloc(sizeof(Node));
  88. node = node->next;
  89. node->next = NULL;
  90.  
  91. // 这里还是没搞太懂为什么要+2,后面有'\0',那只需要+1就行了,为什么
  92. // 还要+2,没搞懂。
  93. char buf[BUFSIZE+];
  94. ssize_t amt;
  95. ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE;
  96. amt = read(fd, buf, amt2);
  97. if (amt != amt2) {
  98. fprintf(stderr, "unable to read file: %s\n", argv[i]);
  99. return ;
  100. }
  101. buf[amt2] = '\0'; // 字符串结尾
  102. // 先转成unix文档
  103. to_unix(buf);
  104. if (ending == UNIX) {
  105. strcpy(node->buf, buf);
  106. } else {
  107. // 这里BUFSIZE*2的主要原因应该是怕所有的都是换行符,这样转换出来
  108. // 就是*2了,但是没搞懂为什么要+3,个人感觉最多有个+1就行了。
  109. char buf2[(BUFSIZE*)+];
  110. unix_to_dos(buf2, buf);
  111. strcpy(node->buf, buf2);
  112. }
  113. len -= amt2;
  114. }
  115.  
  116. // 将文件长度修改为0,并重新从文件头开始
  117. ftruncate(fd, );
  118. lseek(fd, , SEEK_SET);
  119. // 循环将链表中的内容写入文件,并释放链表中的内容
  120. while (root) {
  121. ssize_t amt2 = strlen(root->buf);
  122. if (amt2 > ) {
  123. ssize_t amt = write(fd, root->buf, amt2);
  124. if (amt != amt2) {
  125. fprintf(stderr, "unable to write file: %s\n", argv[i]);
  126. return ;
  127. }
  128. }
  129. node = root;
  130. root = root->next;
  131. free(node);
  132. }
  133. }
  134. close(fd);
  135. }
  136. return ;
  137. }
  138.  
  139. // 这里相当于是字符的的不断的拷贝
  140. void
  141. to_unix(char* buf)
  142. {
  143. char* p = buf;
  144. char* q = buf;
  145. while (*p) {
  146. if (p[] == '\r' && p[] == '\n') {
  147. // dos
  148. *q = '\n';
  149. p += ;
  150. q += ;
  151. }
  152. else if (p[] == '\r') {
  153. // old mac
  154. *q = '\n';
  155. p += ;
  156. q += ;
  157. }
  158. else {
  159. *q = *p;
  160. p += ;
  161. q += ;
  162. }
  163. }
  164. *q = '\0';
  165. }
  166.  
  167. // 这里和to_unix的动作正好相反
  168. void
  169. unix_to_dos(char* buf2, const char* buf)
  170. {
  171. const char* p = buf;
  172. char* q = buf2;
  173. while (*p) {
  174. if (*p == '\n') {
  175. q[] = '\r';
  176. q[] = '\n';
  177. q += ;
  178. p += ;
  179. } else {
  180. *q = *p;
  181. p += ;
  182. q += ;
  183. }
  184. }
  185. *q = '\0';
  186. }

Android development tools line_endings hacking的更多相关文章

  1. ADT Android Development Tools

    ADT(Android Development Tools)在Eclipse编译IDE环境中,需安装ADT(Android Developer Tools)Plug-in,这是Android在Ecli ...

  2. ADT-bundle(Android Development Tools)环境配置

    Android开发环境有两套比较主流的:ADT-bundle和Android Studio,前者是Eclipse插件的形式进行开发,后者是Android的官方IDE. ADT环境的配置与调试:(1)安 ...

  3. Android Development Tools 发生checkAndLoadTargetData错误

    之前使用时没有出现任何问题的,我把D:\IDE\ADT\adt-bundle-windows-x86_64-20140321\eclipse目录下面的 eclipse.exe重名名为adt.exe并设 ...

  4. 在eclipse里卸载已安装的插件[例如Android Development Tools ADT]

    在eclipse里卸载已安装的插件                                        有四种方法: 1.到plugins和features目录中找到你要卸载的插件的文件夹, ...

  5. android 安装 出现Android Native Development Tools不能安装

    Software being installed: Android Native Development Tools 20.0.0.v201206242043-391819 (com.android. ...

  6. Websites for more Android development information

    There is a vibrant, helpful Android developer community on the Web. Here are a numberof useful websi ...

  7. android sdk tools 一览

    ANDROID SDK ADKROID SDK的工具划分为两部分,一部分是SDK tools,与平台无关,另一部分是Platform tools支持最新的安卓平台   SDK tools有 SDK m ...

  8. Could not install the app on the device, read the error above for details. Make sure you have an Android emulator running or a device connected and have set up your Android development environment:

    Administrator@DESKTOP-EHCTIOR MINGW64 /d/react-native-eyepetizer (master) $ react-native run-android ...

  9. [Android]Eclipse 安装 ADT[Android Development Tooling] 失败的两种解决办法

    原因 最近想在新装的 Win7 里搭建一下 Android 的开发环境,虽然现在有 Android Studio 了,不过还是习惯 Eclipse 一点.众所周知的原因,Eclipse 直接安装 AD ...

随机推荐

  1. Socket 阻塞模式和非阻塞模式

    阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...

  2. iOS上的jQuery.on()冒泡事件绑定 以及 iOS绝对定位元素中的输入框

    上周遇到两个坑. 一是jQuery的on方法 事件冒泡,在iOS中有问题. $("body").on("click",".contentup" ...

  3. 《head first java 》读书笔记(五)

    Updated 2014/04/09 P581--P615 如何组织.包装与部署Java程序. 部署的选择 本机: Executable Jar 两者之间的结合: Web Start, RMI app ...

  4. LVS+Keepalived实现高可用集群

    LVS+Keepalived实现高可用集群来源: ChinaUnix博客 日期: 2009.07.21 14:49 (共有条评论) 我要评论 操作系统平台:CentOS5.2软件:LVS+keepal ...

  5. C#中sealed关键字

    C#中sealed关键字 1. sealed关键字     当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承.类似于Java中final关键字.     在下面的示例中,类 B ...

  6. javascript背景淡入淡出

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  7. zend studio 10破解/汉化(转发)

    转发:http://blog.csdn.net/qq1355541448/article/details/16807429 Zend Studio 10正式版破解及汉化 2013年03月12日 ⁄ P ...

  8. SQLite数据库的体系结构(翻译自sqlite.org)

    $1 简介    本文档描述了SQLite库的体系结构,这些信息对那些想理解和修改SQLite的内部工作机制的人是有用的.    下图显示了SQLite的主要组成部件及其相互关系,下面的内容将描述每一 ...

  9. 开源调度框架Quartz最佳实践

    开源调度框架Quartz最佳实践 Quartz是一个Java调度框架,当前的最新版本为2.2.1. 以Quartz 2.2.1版为例,Quartz最佳实践(用于生产系统)总结如下: 1.跳过更新检查Q ...

  10. Spring两种实现AOP的方式

    有两种实现AOP的方式:xml配置文件的方式和注解的形式 我们知道通知Advice是指对拦截到的方法做什么事,可以细分为 前置通知:方法执行之前执行的行为. 后置通知:方法执行之后执行的行为. 异常通 ...