📄 utils.c
字号:
char cptr[4096]; if (idx+1 >= argc || strlen(argv[idx+1]) == 0){ snprintf(cptr, 4096, "Missing value for parameter '%s'.", argv[idx]); AddError(cptr); return; } /* check: "-" is valid but "-<alpha>" is not */ if (strlen(argv[idx+1])>1 && *argv[idx+1] == '-' && isalpha((int)argv[idx+1][1])){ snprintf(cptr, 4096, "Missing value for parameter '%s'.", argv[idx]); AddError(cptr); return; } cptr[0] = '\0'; switch (type){ case TYPE_STRING: /* check: "-" is valid but "-<string>" is not */ if (*argv[idx+1] == '-' && strcmp(argv[idx+1], "-")){ snprintf(cptr, 4096, "Missing value for parameter '%s'.", argv[idx]); *(char**)dest = NULL; } else *(char**)dest = strdup(argv[idx+1]); break; case TYPE_INT: if (*argv[idx+1] == '-' || isdigit((int)*argv[idx+1])) *(int*)dest = atoi(argv[idx+1]); else{ snprintf(cptr, 4096, "Invalid value for parameter '%s'.", argv[idx]); *(int*)dest = (int)0; } break; case TYPE_UNSIGNED: if (isdigit((int)*argv[idx+1])) *(unsigned*)dest = atoi(argv[idx+1]); else{ snprintf(cptr, 4096, "Invalid value for parameter '%s'.", argv[idx]); *(unsigned*)dest = 0u; } break; case TYPE_FLOAT: if (*argv[idx+1] == '-' || isdigit((int)*argv[idx+1])|| *argv[idx+1] == '.') *(float*)dest = atof(argv[idx+1]); else{ snprintf(cptr, 4096, "Invalid value for parameter '%s'.", argv[idx]); *(float*)dest = (float)0.0; } break; default: snprintf(cptr, 4096, "Internal: Unable to assign value to option '%s'.", argv[idx]); } if (cptr[0] != '\0') AddError(cptr);}/* Error handling and error reporting functions */unsigned NumErrors = 0;char **ErrorMessages = NULL;/*****************************************************************************Description: Add a message given by msg to a list of error messages.Return value: The function does not return a value.*****************************************************************************/void AddError(char *msg){ if (msg == NULL) return; NumErrors++; ErrorMessages = MyRealloc(ErrorMessages, NumErrors * sizeof(char*)); ErrorMessages[NumErrors-1] = strdup(msg);}/*****************************************************************************Description: Print all error messages in the list, then clear all messages from the list.Return value: The function does not return a value.*****************************************************************************/void PrintErrors(){ int i; for (i = 0; i < NumErrors; i++){ fprintf(stderr, "Error: %s\n", ErrorMessages[i]); free(ErrorMessages[i]); } free(ErrorMessages); ErrorMessages = NULL; NumErrors = 0;}/*****************************************************************************Description: Clear all messages from the list of error messages.Return value: The function does not return a value.*****************************************************************************/void ClearErrors(){ int i; for (i = 0; i < NumErrors; i++) free(ErrorMessages[i]); free(ErrorMessages); ErrorMessages = NULL; NumErrors = 0;}/*****************************************************************************Description: Return the number of error messages in the list.Return value: The number of error messages in the list.*****************************************************************************/unsigned CheckErrors(){ return NumErrors;}/* Message buffering and reporting functions */unsigned NumMessages = 0;char **Messages = NULL;/*****************************************************************************Description: Add a message given by msg to a list of messages.Return value: The function does not return a value.*****************************************************************************/void AddMessage(char *msg){ if (msg == NULL) return; NumMessages++; Messages = MyRealloc(Messages, NumMessages * sizeof(char*)); Messages[NumMessages-1] = strdup(msg);}/*****************************************************************************Description: Clear all messages from the list of messages.Return value: The function does not return a value.*****************************************************************************/void ClearMessages(){ int i; for (i = 0; i < NumMessages; i++) free(Messages[i]); free(Messages); Messages = NULL; NumMessages = 0;}/*****************************************************************************Description: Print all error messages in the list, then clear all messages from the list.Return value: The function does not return a value.*****************************************************************************/void PrintMessages(){ int i; for (i = 0; i < NumMessages; i++) fprintf(stderr, "%s\n", Messages[i]); ClearMessages();}/*****************************************************************************Description: Return the number of messages in the list.Return value: The number of error messages in the list.*****************************************************************************/unsigned CheckMessages(){ return NumMessages;}/* Functions for a simple progress meter */int ProgressTargetValue = 0;int ProgressOldState = -1;time_t ProgressOldTime = 0;time_t ProgressStartTime = 0;/*****************************************************************************Description: Initialize the progress meter. The progress meter assumes that the state of the progress is indicated by a value which ranges from 0 (no progress yet) to max (task completed). A negative value for max indicates that the maximum value is not known.Return value: The function does not return a value.*****************************************************************************/void InitProgressMeter(int max){ ProgressTargetValue = max; ProgressOldState = -1; ProgressOldTime = 0; ProgressStartTime = time(NULL);}/*****************************************************************************Description: Print the progress. state indicates the progress where 0 (no progress yet), and max (task completed). If max is not known (a negative value for max indicates this), then the state value is printed directly. If max is known, then an estimated time remaining value is printed. Old states are deleted before the new state is printed.Return value: The function does not return a value.*****************************************************************************/void PrintProgress(int state){ time_t t; t = time(NULL); if (t - ProgressOldTime < 1) /* Print progress no more than every 1 second */ return; if (ProgressTargetValue < 0){ /* If we don't know the target value */ if (ProgressOldState >= 0){ /* This is not the first time we print */ int i; for (i = 0; i <= (int)log10f(ProgressOldState); i++) fputc('\b', stderr); /* Remove the old state */ } fprintf(stderr, "%u", state); } else{ time_t remain; remain = (time_t)(t - ProgressStartTime)*((float)ProgressTargetValue/state-1.0); if (ProgressOldState >= 0) /* This is not the first time we print */ fprintf(stderr, "\b\b\b\b\b"); /* Remove the old state */ if (remain < 100) fprintf(stderr, "%2dsec", (int)remain); /* Remaining time is seconds*/ else if (remain/60 < 100) fprintf(stderr, "%2dmin", (int)remain/60); /* Remaining time is minutes*/ else if (remain/3600 < 100) fprintf(stderr, "%2dhrs", (int)remain/3660);/* Remaining time is hours */ else if (remain/86400 < 100) fprintf(stderr, "%2dday", (int)remain/8640);/* Remaining time is days */ else fprintf(stderr, "TIME!"); /* Remaining time exceeds 99 days!! */ } ProgressOldState = state; ProgressOldTime = t;}/*****************************************************************************Description: Delete old progress values if there was progress printed in the past.Return value: The function does not return a value.*****************************************************************************/void StopProgressMeter(){ if (ProgressOldState < 0) return; if (ProgressTargetValue < 0){ /* If we don't know the target value */ int i; for (i = 0; i <= (int)log10f(ProgressOldState); i++) fputc('\b', stderr); /* Remove the old state */ } else fprintf(stderr, "\b\b\b\b\b"); /* Remove the old state */}/* Math and logic functions *//*****************************************************************************Description: Check whether the values in val1 and val2 are approximately the same. The deviation value specifies by how many percent val1 and val2 may differ in order to qualify as being approximately the same.Return value: 1 if val1 and val2 are approximately the same in value. 0 else*****************************************************************************/int approx(float val1, float val2, float deviation){ if (fmaxf(fabsf(val2), fabsf(val1)) * deviation >= fabsf(val2 - val1)) return 1; else return 0;}/*****************************************************************************Description: Check whether val1 and val2 are similar in value. The threshold value for the similarity specifies by how much the val1 and val2 may be different in order to qualify as being similar.Return value: 1 if val1 and val2 are similar. 0 else*****************************************************************************/int similar(float val1, float val2, float threshold){ if (fabs(val2 - val1) <= fabs(threshold)) return 1; else return 0;}/*****************************************************************************Description: Initializer of Bitcounter.Return value: number of '1' bits set in array.*****************************************************************************/int *BitInit(int size){ int *array, i; array = MyMalloc(size * sizeof(int)); for (i = 0; i < size; i++) array[i] = i; return array;}/*****************************************************************************Description: Count number of bits in array. Array is of size bytes. Works only for arrays with 32-bit ints.Return value: number of '1' bits set in array.*****************************************************************************/int BitCount(int *array, int size){ int count; static int *bits_in_char = NULL; if (!bits_in_char) bits_in_char = BitInit(256); count = 0; while (--size >= 0){ count += bits_in_char [array[size] & 0xffu] + bits_in_char [(array[size] >> 8) & 0xffu] + bits_in_char [(array[size] >> 16) & 0xffu] + bits_in_char [(array[size] >> 24) & 0xffu] ; } return count;}/* File handling functions *//*****************************************************************************Description: This is a fail-save equivalent to fopen which expects the same parameters, and returns the same value as fopen. The difference is that the function does not return on error. Instead it prints an error message to stderr, then exits immediately.Return value: Same is in fopen.*****************************************************************************/FILE *MyFopen(const char *path, const char *mode){ FILE *stream = NULL; if (path == NULL || mode == NULL){ fprintf(stderr, "\nError: Call to MyFopen with NULL parameters\n"); exit(0); } else if (!strcmp(path, "-")){ if (*mode == 'r') return stdin; else if (*mode == 'w') return stdout; } if ((stream = fopen(path, mode)) == NULL){ fprintf(stderr, "\nError: Unable to open file '%s'\n", path); exit(0); } return stream;}/*****************************************************************************Description: This is a fail-save equivalent to fclose which expects the same parameters, and returns the same value as fclose.Return value: Same as in fclose*****************************************************************************/int MyFclose(FILE *stream){ if (stream != NULL) return fclose(stream); else return 0;}/*****************************************************************************Description: Returns the compress status of a existing file pointed to by <path>.Return value: GZIP if file is gzip compressed. BZIP if file is bzip2 compressed. RAW else.*****************************************************************************/int GetCompressStatus(const char *path, char *mode){ FILE *myfile; unsigned int buf = 0; myfile = MyFopen(path, mode); if (fread(&buf, 1, 2, myfile) < 2){ /* Attempt to get the magic number */ MyFclose(myfile); /* Empty or very small files are */ return RAW; /* assumed RAW */ } MyFclose(myfile); if (buf == 0x8b1f) /* Magic number of a gzip file */ return GZIP; else if (buf == 0x5a42)/* Magic number of a bzip2 file */ return BZIP; else return RAW; /* Neither BZIP2 nor GZIP */ }/* End of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -