📄 comp_conv.c
字号:
/* comp_conv.c -- Magic C++ compile output format conversion program (Mostly) portable public-domain implementation -- Copyright(C) 2003 Magicunix Infomation Technology Limited This file is part of magicd. magicd is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. For details, see the Magic C++ World-Wide-Web page, `http://www.magicunix.com', or send a mail to the Magic C++ developers <support@magicunix.com>. */#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include "info.h"#include "comp_conv.h"#include "tools.h"#define DIR_LENGTH 300/*############################################################################ Args:# 1 name of machine# 2 working directory# 3 makefile # 4 make target###########################################################################*/int debug = 0; /*no debug mode here*//*szLine - the content of lineszFilename - the file name which error or warning is happened.nLinenum - the line number of that error or warningszErrorinfo - the error infomations*/int parseline(char *szLine , char *szFilename , char *szErrorinfo ){ char szToken[ 1024 ]; char *stopstring; char *p1 = NULL; char *p2 = NULL; char *p3 = NULL; char *p4 = NULL; int nLinenum; /*find :line linenum format*/ /* example: SCO "aaa.c", line 6: error:infomation... "aaa.c", line 6: warning:infomation... */ p1 = (char *)strstr( szLine , "line"); memset(szToken , 0 , sizeof(szToken)); /*is the next token is a number?*/ if( p1 != NULL) { p2 = skipToNonWhite( p1 + 4 );/*a next nonwhite char after 'line'*/ if( p2 && isdigit( *p2 ) ) { if( ( nLinenum = strtod( p2 , &stopstring ) ) != 0 || ( *p2 == 0 && *(p2 + 1) == ' ' ) ) { /*get the filename*/ p3 = (char *)strchr( szLine , '\"'); if(!p3 || p3 > p1 ) return -1; p4 = (char *)strchr( p3 + 1 , '\"'); if(!p4 || p4 > p1 ) return -1; strncpy( szFilename , p3 + 1 , p4 - p3 - 1); strcpy( szErrorinfo , stopstring ); return nLinenum; } } } else { /*gcc output like this:*/ /* filename.c:linenum:warning:infomation... filename.c:linenum: infomation... */ p1 = (char *)strchr(szLine , ':'); if( !p1 ) return -1; p2 = skipToNonWhite( p1 + 1);/*the next nonwhite char after ':'*/ if( ( nLinenum = strtod( p1 + 1 , &stopstring ) ) != 0 || ( *p2 == 0 && *(p2 + 1) == ' ' ) ) { /*get the filename*/ strncpy( szFilename , szLine , p1 - szLine ); strcpy( szErrorinfo , stopstring ); return nLinenum; } } return -1;}/*skip to next non white char*/char * skipToNonWhite(char *chBegin ){ char *p = chBegin; while( *p == ' ' || *p == '\t') p++; if( *p == '\0') return NULL; return p;}/*is it changed current working directory*//*just like :make[1]: Entering directory `/path/to/'*//*or Leaving directory `/path/to'*//*return zero for path has been changed*//*return 1 for path has been changed*/int Checkdir (char *szLine ,char * szCurWorkdir ,char * szWorkdir ) { char *p = NULL; p = (char *)strstr( szLine , "Entering directory"); if( p ) { char *p1 = NULL; char *p2 = NULL; p1 = (char *)strchr( p , '`' ); if( !p1 ) return 0; p2 = (char *)strchr ( p1 + 1 , '\'' ); if( !p2 ) return 0; memset( szCurWorkdir , 0 , DIR_LENGTH ); strncpy( szCurWorkdir , p1 + 1 , p2 - p1 - 1); /*the last char should not be '/'*/ if( szCurWorkdir[ p2 - p1 - 2] == '/' ) szCurWorkdir[ p2 - p1 - 2] = '\0'; else szCurWorkdir[ p2 - p1 - 1] = '\0'; return 1; } else if ( p = (char *)strstr( szLine , "Leaving directory") ) { strcpy( szCurWorkdir , szWorkdir); return 1; } return 0; }int main(int argc , char **argv){ /*for test, read in from test.txt*/ char szMachine[ 50 ] ; char szWorkdir[ DIR_LENGTH ]; char szMakefile[ 100 ]; char szMakeTar[ 50 ]; char szLine[ 1024 ]; /*following infomation is parsed from the compiler's output*/ char szFilename[ 200 ]; int nLinenum; char szErrorinfo[1024]; char szCurWorkdir[ DIR_LENGTH ]; char szOldWorkdir[ DIR_LENGTH ];/*in which directory to exec commands?*/ char szCmdline[1024]; int nOpt = 1; char *p1; FILE *lfd; memset(szMachine , 0 , sizeof(szMachine)); memset(szWorkdir , 0 , sizeof(szWorkdir)); memset(szMakefile , 0 , sizeof(szMakefile)); memset(szMakeTar , 0 , sizeof(szMakeTar)); memset(szLine , 0 , sizeof(szLine)); memset(szFilename , 0 , sizeof(szFilename)); memset(szErrorinfo , 0 , sizeof(szErrorinfo)); memset(szCmdline , 0 , sizeof(szCmdline)); memset(szOldWorkdir , 0 , sizeof(szOldWorkdir)); if ( argc != 4 && argc != 5) { printf("invalid arguments\n"); util_err_log("comp_conv: Invalid arguments!" , __FILE__ , __LINE__ , errno); exit( -3 ); } /*get arguments*/ strcpy(szMachine , argv[ nOpt++ ] ); strcpy(szWorkdir , argv[ nOpt++ ] ); strcpy(szMakefile , argv[ nOpt++ ] ); if( argc == 5 ) strcpy(szMakeTar , argv[ nOpt++ ] ); /*get the old working directory*/ if( getcwd(szOldWorkdir , DIR_LENGTH ) == 0 ) { printf("get current working directory failed!\n"); util_err_log("comp_conv: get current working directory failed!" , __FILE__ , __LINE__ , errno); } /*setup the directory to execute the command...*/ if( chdir(szWorkdir) == -1 ) { printf("change current working directory failed!\n"); util_err_log("comp_conv: change current working directory failed!" , __FILE__ , __LINE__ , errno); } sprintf( szCmdline , "make -f %s %s 2>&1" , szMakefile , szMakeTar); if ( (lfd = popen(szCmdline,"r")) == NULL ) { printf("comp_conv open pipe failed!\n"); util_err_log("comp_conv: open pipe failed!" , __FILE__ , __LINE__ , errno); } /*firstly , the current working directory is top most directory*/ strcpy(szCurWorkdir , szWorkdir ); while( util_getline( lfd , 1023 , szLine) != -1) { if( ( nLinenum = parseline(szLine , szFilename , szErrorinfo) ) != -1 ) /*this is a warning or error line*/ { char *p1; /*if the first char in szErrorinfo is ':' */ /*replace it to white space*/ p1 = skipToNonWhite( szErrorinfo ); if( p1 && *p1 == ':' ) *p1 = ' '; printf("//%s%s/%s(%d):%s\n" , szMachine , szCurWorkdir , szFilename , nLinenum , szErrorinfo); continue; } /*is it changed current working directory*/ /*just like :make[1]: Entering directory `/path/to/'*/ /*or Leaving directory `/path/to'*/ Checkdir (szLine , szCurWorkdir , szWorkdir ) ; printf("%s\n" , szLine); } /*restore the directory */ if( chdir(szOldWorkdir) == -1 ) { printf("restore current working directory failed!\n"); util_err_log("comp_conv: restore current working directory failed!" , __FILE__ , __LINE__ , errno); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -