📄 utility.c
字号:
/* Copyright (C) 2001-2002 Mikael Ylikoski * See the accompanying file "README" for the full copyright notice *//** * @file * Various utility functions. * * @author Mikael Ylikoski * @date 2001-2002 */#include <ctype.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "utility.h"/** * calloc or die. */void *my_calloc (size_t nmemb, size_t size) { void *p; p = calloc (nmemb, size); if (!p) { fprintf (stderr, "Error: Out of memory!\n"); exit (1); } return p;}/** * malloc or die. */void *my_malloc (size_t size) { void *p; p = malloc (size); if (!p) { fprintf (stderr, "Error: Out of memory!\n"); exit (1); } return p;}/** * realloc or die. */void *my_realloc (void *ptr, size_t size) { void *p; p = realloc (ptr, size); if (!p) { fprintf (stderr, "Error: Out of memory!\n"); exit (1); } return p;}/** * Duplicate a string. * * @param s string to duplicate * @return A copy of the string. */char *my_strdup (const char *s) { char *dest; int i; if (s == NULL) return NULL; i = strlen (s) + 1; dest = my_malloc (i); return memcpy (dest, s, i);}/** * Get integer valued option. * * @param opts option line * @param str option key * @return Option value, or -1 if there was an error. */intget_opt_int (const char *opts, const char *str) { char *s, *t; int i; if (opts) { s = strstr (opts, str); if (s && (s == opts || s[-1] == ',')) { s += strlen (str); i = strtol (s, &t, 10); if (t != s) return i; } } return -1;}/** * Get float valued option. * * @param opts option line * @param str option key * @return Option value, or -1 if there was an error. */floatget_opt_flt (const char *opts, const char *str) { char *s, *t; float f; if (opts) { s = strstr (opts, str); if (s && (s == opts || s[-1] == ',')) { s += strlen (str); f = strtod (s, &t); if (t != s) return f; } } return -1;}/** * Get string valued option. * * @param opts option line * @param str option key * @return Beginning of option value, or NULL if there was an error. */char *get_opt_str (const char *opts, const char *str) { char *s; int i; if (opts) { s = strstr (opts, str); if (s && (s == opts || s[-1] == ',')) { i = strlen (str); return s + i; } } return NULL;}/** * Match the next characters in a file with a string. * * @param f file to read from * @param str string to match * @return Zero if file matches string, nonzero otherwise. */intmy_fmatch (FILE *f, char *str) { int i, j, ret_val; char sbuf[20], *buf; i = strlen (str); if (i > 20) buf = my_malloc (i); else buf = sbuf; ret_val = -1; j = fread (buf, sizeof(char), i, f); if (j == i) ret_val = strncmp (str, buf, i); if (i > 10) free (buf); return ret_val;}/** * Reads the next non-empty line from stdin into a buffer. * At most SIZE-1 characters of the line are stored, the rest of line * is flushed. * * @param fd file descriptor to read from * @param buf buffer * @param size size of buffer * @return The number of characters stored in the buffer, excluding NULL. */intget_line (FILE *fd, char *buf, int size) { int i, j; if (size < 2) return 0; j = fgetc (fd); while (j == '\n') j = fgetc (fd); if (j == EOF) return 0; buf[0] = j; for (i = 1; i < size - 1; i++) { j = fgetc (fd); if (j == '\n' || j == EOF) { buf[i] = '\0'; return i; } buf[i] = j; } buf[i] = '\0'; for (j = fgetc (fd); j != '\n' && j != EOF; j = fgetc (fd)) ; return i;}#define my_isblank(x) ((x) == ' ' || (x) == '\t')/** * Reads the next non-empty line from stdin into a buffer. * Removes beginning and trailing whitespace. * The character '#' and anything after it on a line is ignored. * At most SIZE-1 characters of the line are stored, the rest of line * is flushed. * * @param fd file descriptor to read from * @param buf buffer * @param size size of buffer * @return The number of characters stored in the buffer, excluding NULL. */intget_line_nows (FILE *fd, char *buf, int size) { int i, j, k; if (size < 2) return 0; for (j = fgetc (fd); ; j = fgetc (fd)) if (isspace (j)) continue; else if (j == '#') { for (j = fgetc (fd); j != '\n'; j = fgetc (fd)) if (j == EOF) return 0; continue; } else if (j == EOF) return 0; else break; buf[0] = j; k = 0; for (i = 1; i < size - 1; i++) { j = fgetc (fd); if (j == '\n' || j == EOF) { if (k) i = k; buf[i] = '\0'; return i; } else if (j == '#') break; else if (my_isblank (j)) { if (!k) k = i; } else if (k) k = 0; buf[i] = j; } if (k) i = k; buf[i] = '\0'; for (j = fgetc (fd); j != '\n' && j != EOF; j = fgetc (fd)) ; return i;}/** * Get next configuration pair from file. * The pair strings are static and exists only until next call of the function. * * @param fd file to read from * @param p pair to store strings in * @return Nonzero if ok, or zero otherwise. */intget_next_configuration (FILE *fd, conf_pair *p) { static char buf[128]; int i, j; p->key = NULL; p->value = NULL; j = get_line_nows (fd, buf, 128); if (j == 0) return 0; p->key = buf; for (i = 0; i < j; i++) if (my_isblank (buf[i])) break; buf[i] = '\0'; if (i == j) return 1; for (i++; i < j; i++) if (!my_isblank (buf[i])) break; p->value = &buf[i]; return 1;}/** * Get next key from file. * At most 25 characters are allowed in the key. * * @param fd file to read from * @return A static buffer with the key value, or NULL if there were an error. */const char *get_next_key (FILE *fd) { static char buf[27]; int i, j; for (j = fgetc (fd); ; j = fgetc (fd)) if (isspace (j)) continue; else if (j == '#') { for (j = fgetc (fd); j != '\n'; j = fgetc (fd)) if (j == EOF) return NULL; continue; } else if (j == EOF) return NULL; else break; buf[0] = j; for (i = 1; i < 26; i++) { j = fgetc (fd); if (j == '\n' || j == '#' || j == EOF) { ungetc (j, fd); buf[i] = '\0'; return buf; } else if (my_isblank (j)) { buf[i] = '\0'; return buf; } buf[i] = j; } return NULL;}/** * Get next value from file. * At most 25 characters are allowed in the key. * * @param fd file to read from * @return A static buffer with the key value, or NULL if there were an error. */const char *get_next_value (FILE *fd) { static char buf[27]; int i, j, k; for (j = fgetc (fd); ; j = fgetc (fd)) if (isspace (j)) continue; else if (j == '#') { for (j = fgetc (fd); j != '\n'; j = fgetc (fd)) if (j == EOF) return NULL; continue; } else if (j == EOF) return NULL; else break; buf[0] = j; k = 0; for (i = 1; i < 26; i++) { j = fgetc (fd); if (j == '\n' || j == EOF) { if (k) i = k; buf[i] = '\0'; return buf; } else if (j == '#') break; else if (my_isblank (j)) { if (!k) k = i; } else if (k) k = 0; buf[i] = j; } if (k) i = k; buf[i] = '\0'; for (j = fgetc (fd); j != '\n' && j != EOF; j = fgetc (fd)) ; return NULL;}/** * Flush until start of next key. * * @param fd file to read from */voidflush_next_value (FILE *fd) { int i; for (i = fgetc (fd); i != EOF && i != '\n'; i = fgetc (fd)) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -