|
|
1.1 root 1: /*
2: Hatari - str.c
3:
1.1.1.6 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: String functions.
8: */
1.1.1.3 root 9: const char Str_fileid[] = "Hatari str.c : " __DATE__ " " __TIME__;
1.1 root 10:
1.1.1.3 root 11: #include <stdio.h>
1.1 root 12: #include <ctype.h>
13: #include <stdbool.h>
1.1.1.7 ! root 14: #include <stdlib.h>
1.1.1.3 root 15: #include <SDL_types.h>
16: #include "configuration.h"
1.1 root 17: #include "str.h"
18:
19:
20: /**
21: * Remove whitespace from beginning and end of a string.
22: * Returns the trimmed string (string content is moved
23: * so that it still starts from the same address)
24: */
25: char *Str_Trim(char *buffer)
26: {
27: int i, linelen;
28:
29: if (buffer == NULL)
30: return NULL;
31:
32: linelen = strlen(buffer);
33:
34: for (i = 0; i < linelen; i++)
35: {
1.1.1.7 ! root 36: if (!isspace((unsigned char)buffer[i]))
1.1 root 37: break;
38: }
39:
40: if (i > 0 && i < linelen)
41: {
42: linelen -= i;
43: memmove(buffer, buffer + i, linelen);
44: }
45:
46: for (i = linelen; i > 0; i--)
47: {
1.1.1.7 ! root 48: if (!isspace((unsigned char)buffer[i-1]))
1.1 root 49: break;
50: }
51:
52: buffer[i] = '\0';
53:
54: return buffer;
55: }
56:
57:
58: /**
59: * Convert a string to uppercase in place.
60: */
61: char *Str_ToUpper(char *pString)
62: {
63: char *str = pString;
64: while (*str)
65: {
1.1.1.7 ! root 66: *str = toupper((unsigned char)*str);
1.1 root 67: str++;
68: }
69: return pString;
70: }
71:
72:
73: /**
1.1.1.4 root 74: * Convert string to lowercase in place.
1.1 root 75: */
76: char *Str_ToLower(char *pString)
77: {
78: char *str = pString;
79: while (*str)
80: {
1.1.1.7 ! root 81: *str = tolower((unsigned char)*str);
1.1 root 82: str++;
83: }
84: return pString;
85: }
86:
87:
88: /**
1.1.1.4 root 89: * truncate string at first unprintable char (e.g. newline).
1.1 root 90: */
91: char *Str_Trunc(char *pString)
92: {
93: int i = 0;
94: char *str = pString;
95: while (str[i] != '\0')
96: {
97: if (!isprint((unsigned)str[i]))
98: {
99: str[i] = '\0';
100: break;
101: }
102: i++;
103: }
104: return pString;
105: }
106:
107:
108: /**
109: * check if string is valid hex number.
110: */
111: bool Str_IsHex(const char *str)
112: {
113: int i = 0;
114: while (str[i] != '\0' && str[i] != ' ')
115: {
116: if (!isxdigit((unsigned)str[i]))
117: return false;
118: i++;
119: }
120: return true;
121: }
1.1.1.5 root 122:
123:
124: /**
125: * Convert potentially too long host filenames to 8.3 TOS filenames
126: * by truncating extension and part before it, replacing invalid
127: * GEMDOS file name characters with INVALID_CHAR + upcasing the result.
128: *
129: * Matching them from the host file system should first try exact
130: * case-insensitive match, and then with a pattern that takes into
131: * account the conversion done in here.
132: */
133: void Str_Filename2TOSname(const char *source, char *dst)
134: {
135: char *dot, *tmp, *src;
136: int len;
137:
138: src = strdup(source); /* dup so that it can be modified */
139: len = strlen(src);
140:
141: /* does filename have an extension? */
142: dot = strrchr(src, '.');
143: if (dot)
144: {
145: /* limit extension to 3 chars */
146: if (src + len - dot > 3)
147: dot[4] = '\0';
148:
149: /* if there are extra dots, convert them */
150: for (tmp = src; tmp < dot; tmp++)
151: if (*tmp == '.')
152: *tmp = INVALID_CHAR;
153:
1.1.1.6 root 154: /* limit part before extension to 8 chars */
155: if (dot - src > 8)
156: memmove(src + 8, dot, strlen(dot) + 1);
1.1.1.5 root 157: }
1.1.1.6 root 158: else if (len > 8)
159: src[8] = '\0';
160:
161: strcpy(dst, src);
1.1.1.5 root 162: free(src);
163:
1.1.1.6 root 164: /* upcase and replace rest of invalid characters */
1.1.1.5 root 165: for (tmp = dst; *tmp; tmp++)
166: {
167: if (*tmp < 33 || *tmp > 126)
168: *tmp = INVALID_CHAR;
169: else
170: {
171: switch (*tmp)
172: {
173: case '*':
174: case '/':
175: case ':':
176: case '?':
177: case '\\':
178: case '{':
179: case '}':
180: *tmp = INVALID_CHAR;
1.1.1.6 root 181: break;
182: default:
1.1.1.7 ! root 183: *tmp = toupper((unsigned char)*tmp);
1.1.1.5 root 184: }
185: }
186: }
187: }
1.1.1.7 ! root 188:
! 189:
! 190: /**
! 191: * Print an Hex/Ascii dump of Len bytes located at *p
! 192: * Each line consists of Width bytes, printed as an hexa value and as a char
! 193: * (non printable chars are replaced by a '.')
! 194: * The Suffix string is added at the beginning of each line.
! 195: */
! 196: void Str_Dump_Hex_Ascii ( char *p , int Len , int Width , const char *Suffix , FILE *pFile )
! 197: {
! 198: int nb;
! 199: char buf_hex[ 200*3 ]; /* max for 200 bytes per line */
! 200: char buf_ascii[ 200 ];
! 201: char *p_h;
! 202: char *p_a;
! 203: unsigned char c;
! 204: int offset;
! 205:
! 206:
! 207: nb = 0;
! 208: offset = 0;
! 209: p_h = buf_hex;
! 210: p_a = buf_ascii;
! 211: while ( Len > 0 )
! 212: {
! 213: c = *p++;
! 214: sprintf ( p_h , "%2.2x " , c );
! 215: if ( ( c < 0x20 ) || ( c >= 0x7f ) )
! 216: c = '.';
! 217: sprintf ( p_a , "%c" , c );
! 218:
! 219: p_h += 3;
! 220: p_a += 1;
! 221:
! 222: Len--;
! 223: nb++;
! 224: if ( ( nb % Width == 0 ) || ( Len == 0 ) )
! 225: {
! 226: fprintf ( pFile , "%s%6.6x: %-*s %-*s\n" , Suffix , offset , Width*3 , buf_hex , Width , buf_ascii );
! 227: offset = nb;
! 228: p_h = buf_hex;
! 229: p_a = buf_ascii;
! 230: }
! 231:
! 232: }
! 233: }
! 234:
! 235:
! 236:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.