|
发表于 2016-9-10 16:45:04
|
显示全部楼层
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define PATHLEN 1024
- /*** log ***/
- //#define DEBUG
- #ifdef DEBUG
- #define LOG(format, ...) \
- printf("<"__FILE__">(%05d): "format"", __LINE__, ##__VA_ARGS__)
- #else
- #define LOG(format, ...)
- #endif
- /*** log end ***/
- /*** list ***/
- typedef struct _SNode {
- struct _SNode * prev;
- struct _SNode * next;
- char m_acDir[PATHLEN];
- }SNode;
- typedef struct _SList {
- struct _SNode * head;
- struct _SNode * tail;
- }SList;
- SNode * list_node_init(const char * pcDir)
- {
- SNode * pNode = (SNode*)malloc(sizeof(SNode));
- pNode->prev = NULL;
- pNode->next = NULL;
- if(NULL == pcDir)
- {
- memset(pNode->m_acDir, 0, sizeof(pNode->m_acDir));
- }
- else
- {
- strcpy(pNode->m_acDir, pcDir);
- }
- return pNode;
- }
- SList * list_init()
- {
- SList * pList = (SList*)malloc(sizeof(SList));
- SNode * pHead = list_node_init(NULL);
- pList->head = pHead;
- pList->tail = pHead;
- return pList;
- }
- void list_insert_one_node(SNode * pNewNode, SNode * pPreNode, SNode * pCurNode)
- {
- pNewNode->prev = pPreNode;
- pNewNode->next = pCurNode;
- pPreNode->next = pNewNode;
- if(pCurNode != NULL)
- {
- pCurNode->prev = pNewNode;
- }
- }
- void list_delete_one_node(SNode * pNode)
- {
- if(NULL == pNode) {
- return ;
- }
- SNode * pPreNode = pNode->prev;
- SNode * pNextNode = pNode->next;
- pPreNode->next = pNextNode;
- if(pNextNode != NULL) {
- pNextNode->prev = pPreNode;
- }
- free(pNode);
- }
- void list_insert_node_tail(SList * pList, SNode * pNode)
- {
- list_insert_one_node(pNode, pList->tail, NULL);
- pList->tail = pNode;
- }
- void list_insert_tail(SList * pList, const char * pcData)
- {
- SNode * pNode = list_node_init(pcData);
- list_insert_node_tail(pList, pNode);
- }
- SList * list_join(SList * first, SList * second)
- {
- SList * pNewList = list_init();
- pNewList->tail->next = first->head->next;
- first->head->next->prev = pNewList->tail;
- first->tail->next = second->head->next;
- second->head->next->prev = first->tail;
- first->head->next = NULL;
- first->tail = first->head;
- second->head->next = NULL;
- second->tail = second->head;
- return pNewList;
- }
- void list_destroy(SList * pList)
- {
- if(NULL == pList) {
- return ;
- }
- SNode * pCur = pList->head->next;
- while (pCur != NULL)
- {
- SNode * pNext = pCur->next;
- free(pCur);
- pCur = pNext;
- }
- free(pList);
- }
- void list_print(SList * pList)
- {
- #ifdef DEBUG
- SNode * pCur = pList->head->next;
- while (pCur != NULL)
- {
- printf("%s ", pCur->m_acDir);
- pCur = pCur->next;
- }
- printf("\n");
- #endif
- }
- /*** list end ***/
- SList * pstChangePathToList(const char * pcPath)
- {
- SList * pList = list_init();
- char acPath[PATHLEN] = {0};
- strcpy(acPath, pcPath);
- char * pStart = acPath;
- if(pStart[0] == '/') //absolute path
- {
- list_insert_tail(pList, "/");
- pStart++;
- }
- while (*pStart != '\0')
- {
- char * pEnd = strchr(pStart, '/');
- if(NULL == pEnd) //last one dir
- {
- list_insert_tail(pList, pStart);
- break;
- }
- else
- {
- if( pEnd == pStart ) //serial '/'
- {
- pStart++;
- }
- else
- {
- *pEnd = '\0';
- list_insert_tail(pList, pStart);
- pStart = pEnd + 1;
- }
- }
- }
- list_print(pList);
- return pList;
- }
- void vTrimAbsolutePath(SList * pList, char * pcPath)
- {
- SNode * pCur = pList->head->next->next;
- if(NULL == pCur)
- {
- strcpy(pcPath, "/");
- return ;
- }
- //delete '.' and '..'
- while (pCur != NULL)
- {
- if( strcmp(".", pCur->m_acDir) == 0 )
- {
- SNode * pNext = pCur->next;
- list_delete_one_node(pCur);
- pCur = pNext;
- }
- else if( strcmp("..", pCur->m_acDir) == 0 )
- {
- SNode * pNext = pCur->next;
- list_delete_one_node(pCur);
- pCur = pNext;
- if(pCur != NULL && pCur->prev != pList->head->next) { //if prev is root '/'
- list_delete_one_node(pCur->prev);
- }
- }
- else
- {
- pCur = pCur->next;
- }
- }
- pCur = pList->head->next->next;
- if(NULL == pCur)
- {
- strcpy(pcPath, "/");
- return ;
- }
- while (pCur != NULL)
- {
- strcat(pcPath, "/");
- strcat(pcPath, pCur->m_acDir);
- pCur = pCur->next;
- }
- }
- void vTrimRelativePath(SList * pCurList, SList * pSrcList, char * pcPath)
- {
- SList * pList = list_join(pCurList, pSrcList);
- vTrimAbsolutePath(pList, pcPath);
- list_destroy(pList);
- }
- void vGetAbsolutePath(const char * pcCurPath, const char * pcSrc, char * pcDst)
- {
- if(NULL == pcCurPath || NULL == pcSrc || NULL == pcDst) {
- return ;
- }
- LOG("pcCurPath: %s\n", pcCurPath);
- LOG("pcSrc: %s\n", pcSrc);
- SList * pCurList = pstChangePathToList(pcCurPath);
- SList * pSrcList = pstChangePathToList(pcSrc);
- if(pcSrc[0] == '/') //absolute path
- {
- vTrimAbsolutePath(pSrcList, pcDst);
- }
- else //relative path
- {
- vTrimRelativePath(pCurList, pSrcList, pcDst);
- }
- list_destroy(pCurList);
- list_destroy(pSrcList);
- }
- int main()
- {
- int n = 0;
- char acCurPath[PATHLEN] = {0};
- scanf("%d", &n);
- scanf("%s", acCurPath);
- for (int i = 0; i < n; i++)
- {
- char acSrcPath[PATHLEN] = {0};
- char acDstPath[PATHLEN] = {0};
- scanf("%s", acSrcPath);
- vGetAbsolutePath(acCurPath, acSrcPath, acDstPath);
- LOG("acDstPath: %s\n\n", acDstPath);
- printf("%s\n", acDstPath);
- }
- return 0;
- }
复制代码 |
|