/******************************************************************************* * Function : char *strcpy(char *dst, const char *src); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strcpy. ******************************************************************************/ char *strcpy(char *dst, const char *src) { char *p = dst; while (*dst++ = *src++) ; return p; } /******************************************************************************* * Function : char *strncpy(char *dst, const char *src, size_t n); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strncpy. ******************************************************************************/ #include char *strncpy(char *dst, const char *src, size_t n) { char *p = dst; while (n && (*dst++ = *src++)) n--; if (!n) *dst = '\0'; return p; } /******************************************************************************* * Function : int strcmp(const char *s1, const char *s2); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strcmp. ******************************************************************************/ int strcmp(const char *s1, const char *s2) { for (; *s1 && *s1 == *s2; s1++, s2++) ; return *s1 - *s2; } /******************************************************************************* * Function : int strncmp(const char *s1, const char *s2, size_t n); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strncmp. ******************************************************************************/ #include int strncmp(const char *s1, const char *s2, size_t n) { for (; --n && *s1 && *s1 == *s2; s1++, s2++) ; return *s1 - *s2; } /******************************************************************************* * Function : size_t strlen(const char *p); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strlen. ******************************************************************************/ #include size_t strlen(const char *p) { size_t n = 0; while (*p++) n++; return n; } /******************************************************************************* * Function : void *memcpy(void *s, const void *s0, size_t n); * Author : jhlicc@gmai1.c0m * Description: Copy s0 to s, always copy n bytes. Return s. ******************************************************************************/ #include void *memcpy(void *s, const void *s0, size_t n) { char *s1 = s; const char *s2 = s0; while (n--) *s1++ = *s2++; return s; } /******************************************************************************* * Function : void *memmove(void *s, const void *s0, size_t n); * Author : jhlicc@gmai1.c0m * Description: Copy s0 to s, always copy n bytes. Return s. Copying between * objects that overlap will take place correctly. ******************************************************************************/ #include void *memmove(void *s, const void *s0, size_t n) { char *s1 = s; const char *s2 = s0; if (s1 <= s2) while (n--) *s1++ = *s2++; else { s1 += n, s2 += n; while (n--) *--s1 = *--s2; } return s; } /******************************************************************************* * Function : char *strstr(const char *str, const char *sub); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library strstr. ******************************************************************************/ char *strstr(const char *str, const char *sub) { int i, j; for (i = 0; str[i]; i++){ for (j = 0; sub[j]; j++) if (str[i + j] != sub[j]) break; if (!sub[j]) return &str[i]; } return 0; } /******************************************************************************* * Function : int factorial(int n); * Author : jhlicc@gmai1.c0m * Description: Calculate factorial of a number. ******************************************************************************/ int factorial(int n) { if (n == 0) return 1; else return n * factorial(n - 1); } /******************************************************************************* * Function : char toupper(char low); * Author : jhlicc@gmai1.c0m * Description: A user defined implementation of C library toupper. ******************************************************************************/ char toupper(char low) { return low >= 'a' && low <= 'z' ? low + 'A' - 'a' : low ; } /******************************************************************************* * Function : int isprime(unsigned n); * Author : jhlicc@gmai1.c0m * Description: Determine if n is prime, return non-zero if it is prime. ******************************************************************************/ int isprime(unsigned n) { unsigned m; if (n <= 1) return 0; for (m = n - 1; m > 1; m--) if (!(n % m)) return 0; return 1; } /******************************************************************************* * Function : char *strrvs(char *p); * Author : jhlicc@gmai1.c0m * Date : 2006.9 * Description: Reverse a string, e.g. from "9876543210" to "0123456789". ******************************************************************************/ char *strrvs(char *p) { char *p1, *p2, ch; for (p1 = p; *(p1 + 1); p1++) ; for (p2 = p; p2 < p1; p2++, p1--) ch = *p2, *p2 = *p1, *p1 = ch; return p; } /******************************************************************************* * Function : char *compact(char *p); * Author : jhlicc@gmai1.c0m * Date : 2007.9 * Description: Remove the same array elements except the first one from * adjacent elements, e.g. * * 011123333455666777789, len: 21 * 0123456789, len: 10 ******************************************************************************/ char *compact(char *p) { char *p1, *p2; for (p1 = p + 1; *p1; p1++) if (*(p1 - 1) == *p1){ for (p2 = p1; *(p2 - 1); p2++) *(p2 - 1) = *p2; p1--; } return p; } /******************************************************************************* * Function : int *mtxrot1d(int *p, int n); * Author : jhlicc@gmai1.c0m * Date : 2007.10.8 * Description: Rotate an n * n matrix of integers of any size whose length * equals to width by 90 degrees clockwise. 1d for 1 dimension * array version. e.g. * * for a 5 x 5 matrix: | for a 6 x 6 matrix: * | * 1 2 3 4 5 | 1 2 3 4 5 6 * 6 7 8 9 10 | 7 8 9 10 11 12 * 11 12 13 14 15 | 13 14 15 16 17 18 * 16 17 18 19 20 | 19 20 21 22 23 24 * 21 22 23 24 25 | 25 26 27 28 29 30 * | 31 32 33 34 35 36 * 21 16 11 6 1 | * 22 17 12 7 2 | 31 25 19 13 7 1 * 23 18 13 8 3 | 32 26 20 14 8 2 * 24 19 14 9 4 | 33 27 21 15 9 3 * 25 20 15 10 5 | 34 28 22 16 10 4 * | 35 29 23 17 11 5 * | 36 30 24 18 12 6 * ******************************************************************************/ int *mtxrot1d(int *p, int n) { int r, c, i; const int m = n % 2 ? n / 2 - 1 : (n - 1) / 2; const int k = n - 1; for (r = 0; r <= k / 2; r++) for (c = 0; c <= m; c++){ i = *(p + n * r + c ); *(p + n * r + c ) = *(p + n * (k - c) + r ); *(p + n * (k - c) + r ) = *(p + n * (k - r) + k - c); *(p + n * (k - r) + k - c) = *(p + n * c + k - r); *(p + n * c + k - r) = i; } return p; } /******************************************************************************* * Function : void *mtxrot2d(void *mtx); * Author : jhlicc@gmai1.c0m * Date : 2007.10.7 * Description: Rotate a matrix of integers of any size by 90 degrees colckwise * if its length equals to width, 2d for 2 dimensiln array version. ******************************************************************************/ #define MTXROT_SIZE 6 /* length or width of the matrix */ void *mtxrot2d(void *mtx) { int (*p)[MTXROT_SIZE] = mtx; const int M = MTXROT_SIZE % 2 ? MTXROT_SIZE / 2 - 1 : (MTXROT_SIZE - 1) / 2; const int N = MTXROT_SIZE - 1; int r, c, i; for (r = 0; r <= N / 2; r++) for (c = 0; c <= M; c++){ i = p[r ][c ]; p[r ][c ] = p[N - c][r ]; p[N - c][r ] = p[N - r][N - c]; p[N - r][N - c] = p[c ][N - r]; p[c ][N - r] = i; } return p; } /******************************************************************************* * Function : char *wrdrvs(char *p); * Author : jhlicc@gmai1.c0m * Date : 2007.10.4 * Description: Reverse order of space-separated words, e.g. * " hello code monkey " becomes " monkey code hello ". * * [ hello code monkey ] * [hello code monkey ] * [hell code monkey o ] * [hel code monkey lo ] * [he code monkey llo ] * [h code monkey ello ] * [ code monkey hello ] * [ code monkey hello ] * [code monkey hello ] * [cod monkey e hello ] * [co monkey de hello ] * [c monkey ode hello ] * [ monkey code hello ] * [ monkey code hello ] * [ monkey code hello ] * [monkey code hello ] * [monke y code hello ] * [monk ey code hello ] * [mon key code hello ] * [mo nkey code hello ] * [m onkey code hello ] * [ monkey code hello ] * ******************************************************************************/ char *wrdrvs(char *p) { enum STATUS {SPC, NSPC, UNDEF} prestt = UNDEF; char *p1, *p2, *p3, ch; for (p1 = p; *p1; p1++) ; p1--; for (p2 = p; p2 <= p1; p2++) if (*p2 != ' '){ if (prestt == SPC) for (; p2 > p; p2--){ ch = *(p2 - 1); for (p3 = p2; p3 <= p1; p3++) *(p3 - 1) = *p3; *--p3 = ch; p1--; } prestt = NSPC; } else if (*p2 == ' '){ if (prestt == NSPC) for (; p2 > p; p2--){ ch = *(p2 - 1); for (p3 = p2; p3 <= p1; p3++) *(p3 - 1) = *p3; *--p3 = ch; p1--; } prestt = SPC; } return p; } /******************************************************************************* * Function : void sort_sel(char *a, int l, int r); * Author : jhlicc@gmai1.c0m * Date : 2007.10.15 * Description: Selection sort an array of intergers range between index l and * r in ascending order. e.g. sort "312" into "123". ******************************************************************************/ void sort_sel(int *a, int l, int r) { int i, j, n; for (i = l; i < r; i++) for (j = i + 1; j <= r; j++) if (a[i] > a[j]){ n = a[i]; a[i] = a[j]; a[j] = n; } } /******************************************************************************* * Function : void sort_bub(int *a, int l, int r); * Author : jhlicc@gmai1.c0m * Date : 2007.10.16 * Description: Bubble sort an array of intergers range between index l and * r in ascending order. e.g. sort "312" into "123". ******************************************************************************/ void sort_bub(int *a, int l, int r) { int i, n; for (; l < r; r--) for (i = l; i < r; i++) if (a[i] > a[i + 1]){ n = a[i]; a[i] = a[i + 1]; a[i + 1] = n; } } /******************************************************************************* * Function : int search_bin(const int *a, int l, int r, int i); * Author : jhlicc@gmai1.c0m * Date : 2007.10.15 * Description: Binary search a number in an ascending sorted array of integers * range between index l and r. ******************************************************************************/ int search_bin(const int *a, int l, int r, int i) { int n; while (l <= r){ n = (l + r) / 2; if (a[n] == i) return n; else if (a[n] > i) r = n - 1; else if (a[n] < i) l = n + 1; } return -1; } /******************************************************************************* * Function : struct node *list_rvs(struct node *p); * Author : jhlicc@gmai1.c0m * Date : 2007.10.17 * Description: Reverse a single directional non-circle list. e.g. * * p | p * | | | * +-+-+ +---+ +---+ +---+ | +---+ +---+ +---+ +-+-+ * | 1 + -> | 2 + -> | 3 + -> | 4 | | | 1 | <- + 2 | <- + 3 | <- + 4 | * +---+ +---+ +---+ +---+ | +---+ +---+ +---+ +---+ * ******************************************************************************/ extern struct node {int data; struct node *next;}; struct node *list_rvs(struct node *p) { struct node *p1 = p, *p2 = p->next, *p3; while (p2){ p3 = p2->next; p2->next = p1; p1 = p2; p2 = p3; } p->next = 0; p = p1; return p; } /******************************************************************************* * Function : unsigned bitcount(unsigned i); * Author : jhlicc@gmai1.c0m * Date : 2007.11.6 * Description: Count the bit set in an integer. * eg. integer: 0x0110101f, bitcount: 8 ******************************************************************************/ unsigned bitcount(unsigned i) { unsigned cnt = 0, mask; for (mask = 0x1; mask; mask <<= 1) if ((mask & i) == mask) cnt++; return cnt; } /******************************************************************************* * Function : int max(int n1, int n2); * Author : jhlicc@gmai1.c0m * Date : 2007.11.18 * Description: Determine the maximum of two integers. NOTE: This works on twos- * complement machines. It may involve undefined behavior and isn't * portable code. This is a perverse demonstration to such kind of * question, "how to compare two numbers without judgement and * library function calls, e.g. if, :?, etc.". ******************************************************************************/ #include int max(int n1, int n2) { int a[2]; a[0] = n1, a[1] = n2; return a[(unsigned)(a[0] - a[1]) >> sizeof *a * CHAR_BIT - 1]; } #define MAX(N1, N2) (max((N1), (N2))) /******************************************************************************* * Function : int ispalind(const char *s); * Author : jhlicc@gmai1.c0m * Date : 2006.5.8 * Description: Determine if a string is palindromic. Return non-zero if s is * palindromic. e.g. a palindrome "A man, a plan, a canal, Panama!" ******************************************************************************/ #include #include int ispalind(const char *s) { const char *r = s + strlen(s) - 1; for (; s < r; s++, r--){ if (!isalnum(*s)){ r++; continue; } if (!isalnum(*r)){ s--; continue; } if (toupper(*s) != toupper(*r)) return 0; } return 1; } /******************************************************************************* * Function : char *strrmv(char *s1, const char *s2); * Author : jhlicc@gmai1.c0m * Date : 2007.11.27 * Description: Remove sub string s2 from s1. ******************************************************************************/ char *strrmv(char *s1, const char *s2) { int i, j, w = 0, r = 0; for (i = 0; s1[i]; i++){ for (j = 0; s2[j]; j++) if (s1[i + j] != s2[j]) break; if (!s2[j] && j){ if (r) for (; r != i; s1[w++] = s1[r++]) ; else w = i; r = i + j, i = r - 1; } if (r && !s1[i + 1]) for (; r <= i + 1; s1[w++] = s1[r++]) ; } return s1; } /******************************************************************************* * Function : int linecnt(char *file); * Author : jhlicc@gmai1.c0m * Date : 2008.4.12 * Description: C source code line count. No comments & no space lines counted. ******************************************************************************/ #include #include #include int linecnt(char *file) { const char lcmt[] = "/""*", rcmt[] = "*""/", C99cmt[] = "//"; int lcmt_open = 0, /*1:last lcmt still opens; 0:not yet. */ cnt = 0; char buf[1024] = {'\0'}, *p1 = NULL, *p2 = NULL; FILE *fp = NULL; if (!(fp = fopen(file, "r"))){ fprintf(stderr, "%s: File open failed: %s\n", __FILE__, file); return -1; } while (fgets(buf, sizeof buf, fp)){ if (strstr(buf, lcmt) || strstr(buf, rcmt)){ if (p1 = strstr(buf, lcmt)){ lcmt_open = 1; for (p2 = buf; p2 != p1; p2++) if (!isspace(*p2)){ cnt++; break; } } if (p1 = strstr(buf, rcmt)) lcmt_open = 0; } else if (p1 = strstr(buf, C99cmt)){ for (p2 = buf; p2 != p1; p2++) if (!isspace(*p2)){ cnt++; break; } } else if (!lcmt_open){ for (p1 = buf; p1 != buf + strlen(buf); p1++) if (!isspace(*p1)){ cnt++; break; } } } fclose(fp); return cnt; } /******************************************************************************* * Function : int exptab(int n, const char *path) * Author : jhlicc@gmai1.c0m * Date : 2009.8.12 * Description: expand a tab to n blanks in file specified by path ******************************************************************************/ #include #include #include #include int exptab(int n, const char *path) { FILE *fin, *fout; char *path_exp, *exp_suffix = ".exp"; int c; const int cn = n; path_exp = malloc(strlen(path) + strlen(exp_suffix) + 1); if (!path_exp){ fprintf(stderr, "%s: %s\n", __func__, "malloc error"); return -1; } strcat(strcpy(path_exp, path), exp_suffix); fout = fopen(path_exp, "w"); free(path_exp); if (!fout){ fprintf(stderr, "%s(%d): %s\n", __FILE__, __LINE__, "fopen error"); return -1; } fin = fopen(path, "r"); if (!fin){ fprintf(stderr, "%s(%d): %s\n", __FILE__, __LINE__, "fopen error"); return -1; } while ((c=fgetc(fin)) != EOF){ n = cn; if (c == '\t') while (n--) fputc(' ', fout); else fputc(c, fout); } if (!feof(fin) && ferror(fin)){ fprintf(stderr, "%s(%d): %s\n", __FILE__, __LINE__, "stream error"); return -1; } fclose(fin); fclose(fout); return 0; } /* test */ #include int main(int argc, char *argv[]) { int n; char *endp; if (argc != 3){ fprintf(stderr, "usage: %s \n", argv[0]); return -1; } errno = 0; n = strtol(argv[1], &endp, 10); if (n == LONG_MIN || n == LONG_MAX){ perror(__func__); return -1; } if (*endp != '\0'){ fprintf(stderr, "%s: %s\n", __func__, "strtol error"); return -1; } exptab(atoi(argv[1]), argv[2]); return 0; } /******************************************************************************* * File : 7seg.c * Author : jhlicc@gmai1.c0m * Date : 2009.7.2 * Description: seven-segment display * * - * | | * - * | | * - * ******************************************************************************/ static const char segs[16][7 + 1] = { "ABCDEF ", /* 0 */ " BC ", /* 1 */ "AB DE G", /* 2 */ "ABCD G", /* 3 */ " BC FG", /* 4 */ "A CD FG", /* 5 */ "A CDEFG", /* 6 */ "ABC ", /* 7 */ "ABCDEFG", /* 8 */ "ABC FG", /* 9 */ "ABC EFG", /* A */ " CDEFG", /* B */ "A DEF ", /* C */ " BCDE G", /* D */ "A DEFG", /* E */ "A EFG", /* F */ }; void lightup(char seg[5][3], const char c) { char i, *p; if (c >= '0' && c <= '9') i = c - '0'; else if (c >= 'A' && c <= 'Z') i = c - 'A' + 10; else if (c >= 'a' && c <= 'z') i = c - 'a' + 10; p = segs[i]; while (*p){ switch(*p++){ case 'A': seg[0][1] = '-'; break; case 'B': seg[1][2] = '|'; break; case 'C': seg[3][2] = '|'; break; case 'D': seg[4][1] = '-'; break; case 'E': seg[3][0] = '|'; break; case 'F': seg[1][0] = '|'; break; case 'G': seg[2][1] = '-'; break; } } } void showup(char seg[5][3], int lncnt, int clcnt) { int i, j; for (i = 0; i != lncnt; i++){ for (j = 0; j != clcnt; j++){ printf("%c", seg[i][j]); } printf("\n"); } } void cleanup(char seg[5][3], int lncnt, int clcnt) { int i, j; for (i = 0; i != lncnt; i++){ for (j = 0; j != clcnt; j++){ seg[i][j] = ' '; } } } /* test */ #include int main(void) { char seg[5][3] = { " ", " ", " ", " ", " " }; lightup(seg, '8'); showup(seg, 5, 3); cleanup(seg, 5, 3); printf("\n"); lightup(seg, 'b'); showup(seg, 5, 3); return 0; }