Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htio.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      io.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "htio.h"
00022 
00023 #include "htsys.h"              // for sys_is_path_delim
00024 
00025 #include <ctype.h>
00026 #include <errno.h>
00027 #include <limits.h>
00028 #include <stdarg.h>
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <sys/stat.h>
00033 
00034 /*
00035  *      COMMON SYS
00036  */
00037 
00038 #ifndef S_IFMT
00039 #define S_IFMT 0xf000
00040 #endif
00041 
00042 #ifndef S_ISREG
00043 #       ifndef S_IFREG
00044 #               define S_ISREG(m) (0)
00045 #       else
00046 #               define S_ISREG(m) (((m) & S_IFMT)==S_IFREG)
00047 #       endif
00048 #endif
00049 
00050 #ifndef S_ISBLK
00051 #       ifndef S_IFBLK
00052 #               define S_ISBLK(m) (0)
00053 #       else
00054 #               define S_ISBLK(m) (((m) & S_IFMT)==S_IFBLK)
00055 #       endif
00056 #endif
00057 
00058 
00059 #ifndef S_ISCHR
00060 #       ifndef S_IFCHR
00061 #               define S_ISCHR(m) (0)
00062 #       else
00063 #               define S_ISCHR(m) (((m) & S_IFMT)==S_IFCHR)
00064 #       endif
00065 #endif
00066 
00067 #ifndef S_ISDIR
00068 #       ifndef S_IFDIR
00069 #               define S_ISDIR(m) (0)
00070 #       else
00071 #               define S_ISDIR(m) (((m) & S_IFMT)==S_IFDIR)
00072 #       endif
00073 #endif
00074 
00075 #ifndef S_ISFIFO
00076 #       ifndef S_IFFIFO
00077 #               define S_ISFIFO(m) (0)
00078 #       else
00079 #               define S_ISFIFO(m) (((m) & S_IFMT)==S_IFFIFO)
00080 #       endif
00081 #endif
00082 
00083 #ifndef S_ISLNK
00084 #       ifndef S_IFLNK
00085 #               define S_ISLNK(m) (0)
00086 #       else
00087 #               define S_ISLNK(m) (((m) & S_IFMT)==S_IFLNK)
00088 #       endif
00089 #endif
00090 
00091 #ifndef S_ISSOCK
00092 #       ifndef S_IFSOCK
00093 #               define S_ISSOCK(m) (0)
00094 #       else
00095 #               define S_ISSOCK(m) (((m) & S_IFMT)==S_IFSOCK)
00096 #       endif
00097 #endif
00098 
00099 #ifndef S_IRUSR
00100 #define S_IRUSR 0
00101 #endif
00102 #ifndef S_IRGRP
00103 #define S_IRGRP 0
00104 #endif
00105 #ifndef S_IROTH
00106 #define S_IROTH 0
00107 #endif
00108 
00109 #ifndef S_IWUSR
00110 #define S_IWUSR 0
00111 #endif
00112 #ifndef S_IWGRP
00113 #define S_IWGRP 0
00114 #endif
00115 #ifndef S_IWOTH
00116 #define S_IWOTH 0
00117 #endif
00118 
00119 #ifndef S_IXUSR
00120 #define S_IXUSR 0
00121 #endif
00122 #ifndef S_IXGRP
00123 #define S_IXGRP 0
00124 #endif
00125 #ifndef S_IXOTH
00126 #define S_IXOTH 0
00127 #endif
00128 
00129 int sys_basename(char *result, const char *filename)
00130 {
00131 // FIXME: use is_path_delim
00132         char *slash1 = strrchr(filename, '/');
00133         char *slash2 = strrchr(filename, '\\');
00134         char *slash=(slash1>slash2) ? slash1 : slash2;
00135         if (slash) {
00136                 int l=strlen(filename);
00137                 strncpy(result, slash+1, l-(slash-filename)-1);
00138                 result[l-(slash-filename)-1]=0;
00139                 return 0;
00140         }
00141         strcpy(result, filename);
00142         return 0;
00143 }
00144 
00145 int sys_dirname(char *result, const char *filename)
00146 {
00147 // FIXME: use is_path_delim
00148         char *slash1 = strrchr(filename, '/');
00149         char *slash2 = strrchr(filename, '\\');
00150         char *slash = (slash1>slash2) ? slash1 : slash2;
00151         if (slash) {
00152                 strncpy(result, filename, slash-filename);
00153                 result[slash-filename] = 0;
00154                 return 0;
00155         }
00156         strcpy(result, ".");
00157         return 0;
00158 }
00159 
00160 /* filename and pathname must be canonicalized */
00161 int sys_relname(char *result, const char *filename, const char *cwd)
00162 {
00163         const char *f = filename, *p = cwd;
00164         while ((*f == *p) && (*f)) {
00165                 f++;
00166                 p++;
00167         }
00168         if (*f == '/') f++;
00169         const char *last = f, *h = f;
00170         while (*h) {
00171                 if (*h == '/') {
00172                         *(result++) = '.';
00173                         *(result++) = '.';
00174                         *(result++) = '/';
00175                         last = h+1;
00176                 }
00177                 h++;
00178         }
00179         while (f<last) {
00180                 *(result++) = *f;
00181                 f++;
00182         }
00183         *result = 0;
00184         strcat(result, last);
00185         return 0;
00186 }
00187 
00188 int sys_ht_mode(int mode)
00189 {
00190         int m = 0;
00191         if (S_ISREG(mode)) {
00192                 m |= HT_S_IFREG;
00193         } else if (S_ISBLK(mode)) {
00194                 m |= HT_S_IFBLK;
00195         } else if (S_ISCHR(mode)) {
00196                 m |= HT_S_IFCHR;
00197         } else if (S_ISDIR(mode)) {
00198                 m |= HT_S_IFDIR;
00199         } else if (S_ISFIFO(mode)) {
00200                 m |= HT_S_IFFIFO;
00201         } else if (S_ISLNK(mode)) {
00202                 m |= HT_S_IFLNK;
00203         } else if (S_ISSOCK(mode)) {
00204                 m |= HT_S_IFSOCK;
00205         }
00206         if (mode & S_IRUSR) m |= HT_S_IRUSR;
00207         if (mode & S_IRGRP) m |= HT_S_IRGRP;
00208         if (mode & S_IROTH) m |= HT_S_IROTH;
00209         
00210         if (mode & S_IWUSR) m |= HT_S_IWUSR;
00211         if (mode & S_IWGRP) m |= HT_S_IWGRP;
00212         if (mode & S_IWOTH) m |= HT_S_IWOTH;
00213         
00214         if (mode & S_IXUSR) m |= HT_S_IXUSR;
00215         if (mode & S_IXGRP) m |= HT_S_IXGRP;
00216         if (mode & S_IXOTH) m |= HT_S_IXOTH;
00217         return m;
00218 }
00219 
00220 static char *next_delim(char *s, is_path_delim delim)
00221 {
00222         while (*s) {
00223                 s++;
00224                 if (delim(*s)) return s;
00225         }
00226         return NULL;
00227 }
00228 
00229 static int flatten_path(char *path, is_path_delim delim)
00230 {
00231         if (!path || !*path)
00232                 return 0;
00233         char *q = next_delim(path, delim);
00234         int pp = flatten_path(q, delim);
00235         int ll = q ? (q-path-1) : strlen(path)-1;
00236         if ((ll == 2) && (strncmp(path+1, "..", 2) == 0)) {
00237                 if (q) memmove(path, q, strlen(q)+1); else *path = 0;
00238                 pp++;
00239         } else if ((ll == 1) && (strncmp(path+1, ".", 1) == 0)) {
00240                 if (q) memmove(path, q, strlen(q)+1); else *path = 0;
00241         } else if (pp) {
00242                 if (q) memmove(path, q, strlen(q)+1); else *path = 0;
00243                 pp--;
00244         }
00245         return pp;
00246 }
00247 
00248 bool sys_path_is_absolute(const char *filename, is_path_delim delim)
00249 {
00250         return delim(filename[0]) || (isalpha(filename[0]) && (filename[1] == ':'));
00251 }
00252 
00253 int sys_common_canonicalize(char *result, const char *filename, const char *cwd, is_path_delim delim)
00254 {
00255         char *o = result;
00256         if (!sys_path_is_absolute(filename, delim)) {
00257                 if (cwd) strcpy(o, cwd); else return EINVAL;
00258                 int ol = strlen(o);
00259                 if (ol && !delim(o[ol-1])) {
00260                         o[ol] = '/';
00261                         o[ol+1] = 0;
00262                 }
00263         } else *o = 0;
00264         strcat(o, filename);
00265         int k = flatten_path(o, delim);
00266         return (k==0) ? 0 : EINVAL;
00267 }
00268 
00269 char *sys_filename_suffix(const char *fn)
00270 {
00271         const char *s = NULL;
00272         while (fn && *fn) {
00273                 if (sys_is_path_delim(*fn)) s = fn+1;
00274                 fn++;
00275         }
00276         char *p = s ? strrchr(s, '.') : NULL;
00277         return p ? p+1 : NULL;
00278 }
00279 
00280 int sys_tmpfile()
00281 {
00282 // FIXME: this might leak something...
00283     FILE *f = tmpfile();
00284     return fileno(f);
00285 }
00286 
00287 /*
00288  *      COMMON CURSES
00289  */
00290 
00291 #define IS_FGTRANS(c) (VC_GET_BASECOLOR(VCP_FOREGROUND((c)))==VC_TRANSPARENT)
00292 #define IS_BGTRANS(c) (VC_GET_BASECOLOR(VCP_BACKGROUND((c)))==VC_TRANSPARENT)
00293 
00294 vcp vcp_mix(vcp base, vcp layer)
00295 {
00296         int fg, bg;
00297         if (IS_FGTRANS(layer)) {
00298                 fg=VCP_FOREGROUND(base);
00299         } else {
00300                 fg=VCP_FOREGROUND(layer);
00301         }
00302         if (IS_BGTRANS(layer)) {
00303                 bg=VCP_BACKGROUND(base);
00304         } else {
00305                 bg=VCP_BACKGROUND(layer);
00306         }
00307         if (IS_FGTRANS(layer) && (fg != VC_TRANSPARENT) && (fg == bg)) fg=(fg+1)%8;
00308         if (IS_BGTRANS(layer) && (bg != VC_TRANSPARENT) && (fg == bg)) bg=(bg+1)%8;
00309         return VCP(fg, bg);
00310 }
00311 
00312 /*
00313  *      CLASS genericdrawbuf
00314  */
00315 
00316 genericdrawbuf::genericdrawbuf()
00317 {
00318 }
00319 
00320 genericdrawbuf::~genericdrawbuf()
00321 {
00322 }
00323 
00324 void genericdrawbuf::b_line(int px1, int py1, int px2, int py2, int c)
00325 {
00326 }
00327 
00328 void genericdrawbuf::b_putpixel(int px, int py, int c)
00329 {
00330 }
00331 
00332 void genericdrawbuf::text_to_pixel_coord(int tx, int ty, int *px, int *py)
00333 {
00334         *px = tx;
00335         *py = ty;
00336 }
00337 
00338 void genericdrawbuf::pixel_to_text_coord(int px, int py, int *tx, int *ty)
00339 {
00340         *tx = px;
00341         *ty = py;
00342 }
00343 
00344 void genericdrawbuf::b_fill(int x, int y, int w, int h, int c, int ch)
00345 {
00346 }
00347 
00348 int genericdrawbuf::b_printf(int x, int y, int c, char *format, ...)
00349 {
00350         char buf[1024];
00351         va_list arg;
00352         va_start(arg, format);
00353         vsprintf(buf, format, arg);
00354         va_end(arg);
00355         return b_print(x, y, c, buf);
00356 }
00357 
00358 int genericdrawbuf::b_print(int x, int y, int c, char *text)
00359 {
00360         return b_lprint(x, y, c, 0x7fffffff, text);
00361 }
00362 
00363 int genericdrawbuf::b_printw(int x, int y, int c, int *text)
00364 {
00365         return b_lprintw(x, y, c, 0x7fffffff, text);
00366 }
00367 
00368 void genericdrawbuf::b_printchar(int x, int y, int c, int ch)
00369 {
00370 }
00371 
00372 int genericdrawbuf::b_lprint(int x, int y, int c, int l, char *text)
00373 {
00374         return 0;
00375 }
00376 
00377 int genericdrawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00378 {
00379         return 0;
00380 }
00381 
00382 void genericdrawbuf::b_resize(int rw, int rh)
00383 {
00384         size.w+=rw;
00385         size.h+=rh;
00386         b_setbounds(&size);
00387 }
00388 
00389 void genericdrawbuf::b_rmove(int rx, int ry)
00390 {
00391         size.x+=rx;
00392         size.y+=ry;
00393 }
00394 
00395 void genericdrawbuf::b_setbounds(bounds *b)
00396 {
00397         size=*b;
00398 }
00399 
00400 /*
00401  *      CLASS drawbuf
00402  */
00403  
00404 drawbuf::drawbuf(bounds *b)
00405 {
00406         buf=0;
00407         b_setbounds(b);
00408 }
00409 
00410 drawbuf::~drawbuf()
00411 {
00412         if (buf) free(buf);
00413 }
00414 
00415 void drawbuf::b_fill(int x, int y, int w, int h, int c, int ch)
00416 {
00417         x-=size.x;
00418         y-=size.y;
00419         for (int iy=y; iy<y+h; iy++) {
00420                 if (iy<size.h) {
00421                         drawbufch *b=buf+x+iy*size.w;
00422                         for (int ix=x; ix<x+w; ix++) {
00423                                 b->ch=ch;
00424                                 b->c=vcp_mix(b->c, c);
00425                                 b++;
00426                         }
00427                 }
00428         }
00429 }
00430 
00431 void drawbuf::b_printchar(int x, int y, int c, int ch)
00432 {
00433         drawbufch *b=buf+(x-size.x)+(y-size.y)*size.w;
00434         b->ch=ch;
00435         b->c=vcp_mix(b->c, c);
00436 }
00437 
00438 int drawbuf::b_lprint(int x, int y, int c, int l, char *text)
00439 {
00440         int ox=0;
00441         x-=size.x;
00442         y-=size.y;
00443         drawbufch *b=buf+x+y*size.w;
00444         if (y<size.h) {
00445                 while ((ox<size.w) && (*text) && (ox<l)) {
00446                         b->ch=(byte)*text;
00447                         b->c=vcp_mix(b->c, c);
00448                         text++;
00449                         ox++;
00450                         b++;
00451                 }
00452         }
00453         return ox;
00454 }
00455 
00456 int drawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00457 {
00458         int ox=0;
00459         x-=size.x;
00460         y-=size.y;
00461         drawbufch *b=buf+x+y*size.w;
00462         if (y<size.h) {
00463                 while ((ox<size.w) && (*text) && (ox<l)) {
00464                         b->ch=(byte)*text;
00465                         b->c=vcp_mix(b->c, c);
00466                         text++;
00467                         ox++;
00468                         b++;
00469                 }
00470         }
00471         return ox;
00472 }
00473 
00474 void drawbuf::b_setbounds(bounds *b)
00475 {
00476         genericdrawbuf::b_setbounds(b);
00477         if (buf) free(buf);
00478         if (size.w * size.h) {
00479                 buf=(drawbufch*)malloc(sizeof *buf * size.w * size.h);
00480                 drawbufch *bb=buf;
00481                 for (int iy=0; iy<size.h; iy++) {
00482                         for (int ix=0; ix<size.w; ix++) {
00483                                 bb->ch=' ';
00484                                 bb->c=VCP(VC_TRANSPARENT, VC_TRANSPARENT);
00485                                 bb++;
00486                         }
00487                 }
00488         } else buf=0;
00489 }
00490 
00491 /*
00492  *      COMMON KEYB
00493  */
00494  
00495 ht_key ht_unmetakey(ht_key key)
00496 {
00497         switch (key) {
00498                 case K_Alt_A: return K_A;
00499                 case K_Alt_B: return K_B;
00500                 case K_Alt_C: return K_C;
00501                 case K_Alt_D: return K_D;
00502                 case K_Alt_E: return K_E;
00503                 case K_Alt_F: return K_F;
00504                 case K_Alt_G: return K_G;
00505                 case K_Alt_H: return K_H;
00506                 case K_Alt_I: return K_I;
00507                 case K_Alt_J: return K_J;
00508                 case K_Alt_K: return K_K;
00509                 case K_Alt_L: return K_L;
00510                 case K_Alt_M: return K_M;
00511                 case K_Alt_N: return K_N;
00512                 case K_Alt_O: return K_O;
00513                 case K_Alt_P: return K_P;
00514                 case K_Alt_Q: return K_Q;
00515                 case K_Alt_R: return K_R;
00516                 case K_Alt_S: return K_S;
00517                 case K_Alt_T: return K_T;
00518                 case K_Alt_U: return K_U;
00519                 case K_Alt_V: return K_V;
00520                 case K_Alt_W: return K_W;
00521                 case K_Alt_X: return K_X;
00522                 case K_Alt_Y: return K_Y;
00523                 case K_Alt_Z: return K_Z;
00524                 default: return K_INVALID;
00525         }
00526 }
00527 
00528 ht_key ht_lmetakey(ht_key key)
00529 {
00530         switch (key) {
00531                 case K_A: return K_Alt_A;
00532                 case K_B: return K_Alt_B;
00533                 case K_C: return K_Alt_C;
00534                 case K_D: return K_Alt_D;
00535                 case K_E: return K_Alt_E;
00536                 case K_F: return K_Alt_F;
00537                 case K_G: return K_Alt_G;
00538                 case K_H: return K_Alt_H;
00539                 case K_I: return K_Alt_I;
00540                 case K_J: return K_Alt_J;
00541                 case K_K: return K_Alt_K;
00542                 case K_L: return K_Alt_L;
00543                 case K_M: return K_Alt_M;
00544                 case K_N: return K_Alt_N;
00545                 case K_O: return K_Alt_O;
00546                 case K_P: return K_Alt_P;
00547                 case K_Q: return K_Alt_Q;
00548                 case K_R: return K_Alt_R;
00549                 case K_S: return K_Alt_S;
00550                 case K_T: return K_Alt_T;
00551                 case K_U: return K_Alt_U;
00552                 case K_V: return K_Alt_V;
00553                 case K_W: return K_Alt_W;
00554                 case K_X: return K_Alt_X;
00555                 case K_Y: return K_Alt_Y;
00556                 case K_Z: return K_Alt_Z;
00557                 default: return K_INVALID;
00558         }
00559 }
00560 
00561 ht_key ht_metakey(ht_key key)
00562 {
00563         if ((key>=K_A) && (key<=K_Z)) {
00564                 return ht_lmetakey(key);
00565 /*      } else if ((key>=K_Shift_A) && (key<=K_Shift_Z)) {
00566                 return ht_lmetakey( (ht_key) ((int)key-(int)K_Alt_A+(int)K_A));*/
00567         }
00568         return K_INVALID;
00569 }
00570 
00571 static int ht_keys1[K_COUNT];
00572 static int ht_keys2[K_COUNT];
00573 static int ht_keys3[K_COUNT];
00574 
00575 ht_key ht_rawkey2key(int rawkey)
00576 {
00577         for (int i=0; i<K_COUNT; i++) {
00578                 if (ht_keys1[i]==(int)rawkey) return (ht_key)i;
00579                 if (ht_keys2[i]==(int)rawkey) return (ht_key)i;
00580                 if (ht_keys3[i]==(int)rawkey) return (ht_key)i;
00581         }
00582         return K_INVALID;
00583 }
00584 
00585 void ht_set_key(ht_key key, int rawkey)
00586 {
00587         int i = (int)key;
00588         if (i<K_COUNT) {
00589                 if (rawkey == -1) {
00590                         ht_keys1[i] = -1;
00591                         ht_keys2[i] = -1;
00592                         ht_keys3[i] = -1;
00593                 }
00594                 else if ((ht_keys1[i] == -1) || (ht_keys1[i] == rawkey)) ht_keys1[i] = rawkey;
00595                 else if ((ht_keys2[i] == -1) || (ht_keys2[i] == rawkey)) ht_keys2[i] = rawkey;
00596                 else if ((ht_keys3[i] == -1) || (ht_keys3[i] == rawkey)) ht_keys3[i] = rawkey;
00597         }
00598 }

Generated on Fri May 7 21:15:34 2004 by doxygen 1.3.5