/*++ Copyright (c) 1996 Microsoft Corporation Module Name: jd_misc.cpp Abstract: variety of assisting functions - command line parameters parsing - displaying the error messages - creating the random file - creating the unique identifier based on thread and process Author: jaroslad Revision History: 06-01-96 ( Jaroslad ) Original. --*/ #include #include "jd_misc.h" #include #include #include #include #include #include int random (int low, int high) { return ( low+((long)rand()*(long)high)/RAND_MAX ); } /* Sample structure demonstating how to use comand line definition structure TParamDef CmdLineParam[]= { {"c" ,1, &FtpServerIpAddr,TYPE_TCHAR,OPT, "ftp server computer name", "computer"}, {"b", 0, &fStop, TYPE_INT, OPT, "binary flag"}, {"start", 0, &fStart, TYPE_INT, OPT, "start service"}, {"pause", 0, &fPause, TYPE_INT, OPT, "pause service"}, {"s" ,1, &ServiceName, TYPE_TCHAR, MAND,"service name","svc"}, { {NULL,0, NULL , TYPE_TCHAR, OPT, "Place the description of the program here" }; */ void DisplayUsage( _TCHAR **argv, TParamDef *tt) { _tprintf(_T("Usage:\n\t%s "), argv[0]); for(int i=0; tt[i].sw!=0;i++) { if(tt[i].sw[0]==0) //default (do not need switch) parameters { _tprintf(_T("%s "),(tt[i].text_param!=NULL)?tt[i].text_param:_T("parm")); } else { _tprintf(_T("-%s "),tt[i].sw); if(tt[i].param_number==1) _tprintf(_T("[%s] "),(tt[i].text_param!=NULL)?tt[i].text_param:_T("parm")); else if(tt[i].param_number>1) _tprintf(_T("[[%s]...] "),(tt[i].text_param!=NULL)?tt[i].text_param:_T("parm")); } } _tprintf(_T("\n\n")); for(i=0; tt[i].sw!=0; i++) { if(tt[i].sw[0]==0) //default parameters { _tprintf(_T("\"no switch\" %s\n"),tt[i].text_desc); } else if(tt[i].text_desc!=NULL) { _tprintf(_T("-%-6s %s\n"),tt[i].sw,tt[i].text_desc); } } //print description if( tt[i].text_desc!=NULL && tt[i].text_desc[0]!=0) { _tprintf(_T("\nDescription:\n")); _tprintf(_T("%s \n"), tt[i].text_desc); } } void DisplayUsageAndExit( _TCHAR **argv, TParamDef *tt) { DisplayUsage( argv, tt); exit(1); } //structure that makes easy lexical parsing of the command line arguments struct sParamLex { int argc; TCHAR **argv; _TCHAR ParamBuffer[400]; int iCurrentParamChar; //character index within the current parameter being processed int iCurrentParam; //index to the current parameter that is processed public: sParamLex(int argc,_TCHAR **argv):argc(argc),argv(argv){iCurrentParamChar=0; iCurrentParam=1;}; BOOL IsNextSwitch(); BOOL IsEnd(); LPTSTR ReadNext(); }; BOOL sParamLex::IsNextSwitch() { if(IsEnd()) return FALSE; if (argv[iCurrentParam][iCurrentParamChar]==_T('-')) return TRUE; else return FALSE; } BOOL sParamLex::IsEnd() { if(iCurrentParam>=argc) return TRUE; else return FALSE; } LPTSTR sParamLex::ReadNext() { LPTSTR lpszRetval; if (IsEnd()) return NULL; if(IsNextSwitch()) { int i=0; iCurrentParamChar++; //skip '/' or '-' while (argv[iCurrentParam][iCurrentParamChar]!=0 && argv[iCurrentParam][iCurrentParamChar]!=_T(':')) ParamBuffer[i++]=argv[iCurrentParam][iCurrentParamChar++]; if(argv[iCurrentParam][iCurrentParamChar]==_T(':')) iCurrentParamChar++; if(argv[iCurrentParam][iCurrentParamChar]==0) { iCurrentParam++; iCurrentParamChar=0; } ParamBuffer[i]=0; lpszRetval=ParamBuffer; } else { lpszRetval=&argv[iCurrentParam][iCurrentParamChar]; iCurrentParam++; iCurrentParamChar=0; } return lpszRetval; } void ParseParam(int argc, _TCHAR ** argv, TParamDef * tt) { for(int i=0; tt[i].sw!=NULL ; i++) { tt[i].curr_param_read=0; //initialize } sParamLex paramLex(argc,argv); BOOL fParseBegin=TRUE; while(!paramLex.IsEnd()) { int k; if(paramLex.IsNextSwitch()) { _TCHAR * sw = paramLex.ReadNext(); /*find the switch in switch table*/ for( k=0; tt[k].sw!=NULL ;k++) { if(tt[k].sw[0]==0) continue; //skip the default parameters if(_tcscmp(tt[k].sw, sw)==0 /*equal*/ ) break; } if(tt[k].sw == NULL) //switch not found { _tprintf(_T("invalid switch \"%s\"\n"),sw);/*error*/ DisplayUsageAndExit(argv,tt); } } else if( fParseBegin==TRUE && (_tcscmp(tt[0].sw, _T(""))==0 /*equal*/ ) ) { //default parameters (has to be the first record in arg description) k=0; } else { _tprintf(_T("default arguments not expected\n"));/*error*/ DisplayUsageAndExit(argv,tt); } if(tt[k].param_number==0) //switch without parameters { if(paramLex.IsEnd()==FALSE && paramLex.IsNextSwitch()==FALSE) { _tprintf(_T("switch \"%s\" takes no parameters \n"),tt[k].sw); DisplayUsageAndExit(argv,tt); } tt[k].curr_param_read++; *((int *)tt[k].ptr)=1; } else if(tt[k].param_number>0) //swith with more then 0ne parameter { if(paramLex.IsEnd()==TRUE || paramLex.IsNextSwitch()==TRUE) { _tprintf(_T(" switch \"%s\" expects parameter\n"),tt[k].sw);//error DisplayUsageAndExit(argv,tt); } else { _TCHAR * prm; do { prm=paramLex.ReadNext(); if(tt[k].param_number <= tt[k].curr_param_read) { _tprintf(_T("number of parameters for switch -%s exceeds maximum allowed (%d)\n"),tt[k].sw,tt[k].param_number); DisplayUsageAndExit(argv,tt); } if(tt[k].ptr_type==TYPE_TCHAR || tt[k].ptr_type==TYPE_LPCTSTR) *(((_TCHAR **)tt[k].ptr) + tt[k].curr_param_read++)=prm; else if(tt[k].ptr_type==TYPE_INT ||tt[k].ptr_type==TYPE_WORD) *(((int *)tt[k].ptr) + tt[k].curr_param_read++)=_ttoi(prm); else if(tt[k].ptr_type==TYPE_LONG || tt[k].ptr_type==TYPE_DWORD) *(((long *)tt[k].ptr) + tt[k].curr_param_read++)=_ttol(prm); }while (paramLex.IsEnd()==FALSE && paramLex.IsNextSwitch()==FALSE); } }//end tt[k].param_number } // end while for(i=0; tt[i].sw!=0;i++) //check for mandatory switches { if (tt[i].opt_mand==MAND && tt[i].curr_param_read==0) { _tprintf(_T("mandatory switch -%s missing\n"),tt[i].sw); DisplayUsageAndExit(argv,tt); } if(tt[i].param_read!=NULL) // set number of params for switch *tt[i].param_read=tt[i].curr_param_read; } } /****************************************** time_printf *******************************************/ int time_printf(_TCHAR *format, ...) { static CRITICAL_SECTION cs; static BOOL fInit=0; va_list marker; if(fInit==0) { fInit=1; InitializeCriticalSection(&cs); } _TCHAR buf[80]; EnterCriticalSection(&cs); va_start( marker, format ); /* Initialize variable arguments. */ _tprintf(_TEXT("%s - "),_tstrtime(buf)); _vtprintf(format,marker); LeaveCriticalSection(&cs); va_end( marker ); /* Reset variable arguments. */ // printf("%s%s",bufa,bufb); //for multithreaded will be printed as one line return 1; } void error_printf(_TCHAR *format, ...) { va_list marker; va_start( marker, format ); /* Initialize variable arguments. */ _tprintf(_TEXT("Error: ")); int x=_vftprintf(stderr,format,marker); va_end( marker ); /* Reset variable arguments. */ } void fatal_error_printf(_TCHAR *format, ...) { va_list marker; va_start( marker, format ); /* Initialize variable arguments. */ _tprintf(_TEXT("Error: ")); int x=_vftprintf(stderr,format,marker); va_end( marker ); /* Reset variable arguments. */ exit(EXIT_FAILURE); }