Android development tools line_endings hacking

简介: /******************************************************************** * Android development tools line_endings hacking * 说明: * 本文主要是对android源代码中的line_endings开发工具进行了解读, * 目的是为了知道传说中的dos,unix文件之间转换的工作机制。
/********************************************************************
 *       Android development tools line_endings hacking
 * 说明:
 *     本文主要是对android源代码中的line_endings开发工具进行了解读,
 * 目的是为了知道传说中的dos,unix文件之间转换的工作机制。
 *
 *                                  2016-5-3 深圳 南山平山村 曾剑锋
 *******************************************************************/


#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

#define BUFSIZE (1024*8)
static void to_unix(char* buf);
static void unix_to_dos(char* buf2, const char* buf);

// 使用方法
int usage()
{
    fprintf(stderr, "usage: line_endings unix|dos FILES\n"
            "\n"
            "Convert FILES to either unix or dos line endings.\n");
    return 1;
}

// 定义Node数据结构
typedef struct Node {
    struct Node *next;
    char buf[BUFSIZE*2+3];
} Node;

int
main(int argc, char** argv)
{
    // 枚举UNIX,DOS两种数据
    enum { UNIX, DOS } ending;
    int i;

    // 参数个数判断
    if (argc < 2) {
        return usage();
    }

    // 参数比较
    if (0 == strcmp("unix", argv[1])) {
        ending = UNIX;
    }
    else if (0 == strcmp("dos", argv[1])) {
        ending = DOS;
    }
    else {
        return usage();
    }

    // 命令行传入的参数可能有多个,利用for循环进行轮流转换。
    for (i=2; i<argc; i++) {
        int fd;
        int len;

        // force implied
        chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);

        // 打开文件
        fd = open(argv[i], O_RDWR);
        if (fd < 0) {
            fprintf(stderr, "unable to open file for read/write: %s\n", argv[i]);
            return 1;
        }

        // 获取文件大小
        len = lseek(fd, 0, SEEK_END);
        lseek(fd, 0, SEEK_SET);

        // 文件长度正常才有必要进行转换
        if (len > 0) {
            // 创建根节点
            Node* root = malloc(sizeof(Node));
            Node* node = root;
            node->buf[0] = 0; // root节点的buf数据位0

            while (len > 0) {
                // 创建节点,并出示节点
                node->next = malloc(sizeof(Node));
                node = node->next;
                node->next = NULL;

                // 这里还是没搞太懂为什么要+2,后面有'\0',那只需要+1就行了,为什么
                // 还要+2,没搞懂。
                char buf[BUFSIZE+2];
                ssize_t amt;
                ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE;
                amt = read(fd, buf, amt2);
                if (amt != amt2) {
                    fprintf(stderr, "unable to read file: %s\n", argv[i]);
                    return 1;
                }
                buf[amt2] = '\0';   // 字符串结尾
                // 先转成unix文档
                to_unix(buf);
                if (ending == UNIX) {
                    strcpy(node->buf, buf);
                } else {
                    // 这里BUFSIZE*2的主要原因应该是怕所有的都是换行符,这样转换出来
                    // 就是*2了,但是没搞懂为什么要+3,个人感觉最多有个+1就行了。
                    char buf2[(BUFSIZE*2)+3];
                    unix_to_dos(buf2, buf);
                    strcpy(node->buf, buf2);
                }
                len -= amt2;
            }

            // 将文件长度修改为0,并重新从文件头开始
            ftruncate(fd, 0);
            lseek(fd, 0, SEEK_SET);
            // 循环将链表中的内容写入文件,并释放链表中的内容
            while (root) {
                ssize_t amt2 = strlen(root->buf);
                if (amt2 > 0) {
                    ssize_t amt = write(fd, root->buf, amt2);
                    if (amt != amt2) {
                        fprintf(stderr, "unable to write file: %s\n", argv[i]);
                        return 1;
                    }
                }
                node = root;
                root = root->next;
                free(node);
            }
        }
        close(fd);
    }
    return 0;
}

// 这里相当于是字符的的不断的拷贝
void
to_unix(char* buf)
{
    char* p = buf;
    char* q = buf;
    while (*p) {
        if (p[0] == '\r' && p[1] == '\n') {
            // dos
            *q = '\n';
            p += 2;
            q += 1;
        }
        else if (p[0] == '\r') {
            // old mac
            *q = '\n';
            p += 1;
            q += 1;
        }
        else {
            *q = *p;
            p += 1;
            q += 1;
        }
    }
    *q = '\0';
}

// 这里和to_unix的动作正好相反
void
unix_to_dos(char* buf2, const char* buf)
{
    const char* p = buf;
    char* q = buf2;
    while (*p) {
        if (*p == '\n') {
            q[0] = '\r';
            q[1] = '\n';
            q += 2;
            p += 1;
        } else {
            *q = *p;
            p += 1;
            q += 1;
        }
    }
    *q = '\0';
}

 

目录
相关文章
|
Android开发
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
942 0
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
|
7月前
|
Android开发
Android launcher development resources
Android launcher development resources
32 1
|
编解码 IDE Ubuntu
Android Development Studio 初学者教程
今天介绍的是面向初学者的 Android development studio 教程。它是用于 Android 开发的最佳 IDE 之一。在这篇文章中,我将引导你完成安装和设置 Android Studio 的步骤。
153 0
Android Development Studio 初学者教程
|
IDE Java 开发工具
当Android Studio安装时提示couldn‘t detect a java development kit
当Android Studio安装时提示couldn‘t detect a java development kit
161 1
当Android Studio安装时提示couldn‘t detect a java development kit
|
XML IDE 开发工具
android中tools的含义及用法
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 第一部分 安卓开发中,在写布局代码的时候,ide可以看到布局的预览效果。
1469 0
|
Android开发
add 'tools:replace="android:value"' to element at AndroidManifest.xml:25:5-27:34 to over
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.
2025 0
|
Android开发 开发工具
Gradle、 Gradle Android Plugin 、 Build Tools之间关系
gradle一堆坑,原理自己找别的文章吧,看着这个配置就不会有坑了。 先看Gradle,再看 Android Plugin,参考以下图,一定能编译通过。 https://developer.
1292 0