about summary refs log tree commit diff stats
path: root/515parse-float.mu
blob: 40bbb194307b53d96365ea60c9f0ab3a19407024 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# no support for scientific notation yet
fn parse-float-decimal in: (addr stream byte) -> _/xmm1: float {
  var zero: float
  var result/xmm1: float <- copy zero
  var first-iter?/ecx: int <- copy 1/true
  rewind-stream in
  var negative?/edx: int <- copy 0/false
  # first loop: integer part
  var ten/eax: int <- copy 0xa
  var ten-f/xmm2: float <- convert ten
  {
    var done?/eax: boolean <- stream-empty? in
    compare done?, 0/false
    break-if-!=
    var key/eax: byte <- read-byte in
    compare key, 0x2e/decimal-point
    break-if-=
    $parse-float-decimal:body: {
      compare key, 0x2d/-
      {
        break-if-!=
        compare first-iter?, 0/false
        {
          break-if-!=
          abort "parse-float-decimal: '-' only allowed in first position"
        }
        negative? <- copy 1/true
        break $parse-float-decimal:body
      }
      compare key, 0x30/0
      {
        break-if->=
        abort "parse-float-decimal: invalid character < '0'"
      }
      compare key, 0x39/9
      {
        break-if-<=
        abort "parse-float-decimal: invalid character > '9'"
      }
      # key is now a digit
      var digit-value/eax: int <- copy key
      digit-value <- subtract 0x30
      var digit-value-f/xmm3: float <- convert digit-value
      result <- multiply ten-f
      result <- add digit-value-f
    }
    first-iter? <- copy 0/false
    loop
  }
  # second loop: fraction
  var current-position/xmm0: float <- rational 1, 0xa
  {
    var done?/eax: boolean <- stream-empty? in
    compare done?, 0/false
    break-if-!=
    var key/eax: byte <- read-byte in
    compare key, 0x30/0
    {
      break-if->=
      abort "parse-float-decimal: invalid fraction character < '0'"
    }
    compare key, 0x39/9
    {
      break-if-<=
      abort "parse-float-decimal: invalid fraction character > '9'"
    }
    # key is now a digit
    var digit-value/eax: int <- copy key
    digit-value <- subtract 0x30
    var digit-value-f/xmm3: float <- convert digit-value
    digit-value-f <- multiply current-position
    result <- add digit-value-f
    current-position <- divide ten-f
    #
    first-iter? <- copy 0/false
    loop
  }
  # finally, the sign
  compare negative?, 0/false
  {
    break-if-=
    var minus-one/eax: int <- copy -1
    var minus-one-f/xmm2: float <- convert minus-one
    result <- multiply minus-one-f
  }
  return result
}

fn test-parse-float-decimal-zero {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write s, "00"
  var x/xmm1: float <- parse-float-decimal s
  var expected/eax: int <- copy 0
  var expected-f/xmm0: float <- convert expected
  compare x, expected-f
  {
    break-if-=
    draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-zero", 3/fg 0/bg
    move-cursor-to-left-margin-of-next-line 0/screen
    count-test-failure
  }
  draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
}

fn test-parse-float-decimal-integer {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write s, "34"
  var x/xmm1: float <- parse-float-decimal s
  var expected/eax: int <- copy 0x22/34
  var expected-f/xmm0: float <- convert expected
  compare x, expected-f
  {
    break-if-=
    draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-integer", 3/fg 0/bg
    move-cursor-to-left-margin-of-next-line 0/screen
    count-test-failure
  }
  draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
}

fn test-parse-float-decimal-negative-integer {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write s, "-34"
  var x/xmm1: float <- parse-float-decimal s
  var expected/eax: int <- copy -0x22/-34
  var expected-f/xmm0: float <- convert expected
  compare x, expected-f
  {
    break-if-=
    draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-integer", 3/fg 0/bg
    move-cursor-to-left-margin-of-next-line 0/screen
    count-test-failure
  }
  draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
}

fn test-parse-float-decimal-fraction {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write s, "3.4"
  var x/xmm1: float <- parse-float-decimal s
  var expected-f/xmm0: float <- rational 0x22/34, 0xa/10
  compare x, expected-f
  {
    break-if-=
    draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-fraction", 3/fg 0/bg
    move-cursor-to-left-margin-of-next-line 0/screen
    count-test-failure
  }
  draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
}

fn test-parse-float-decimal-negative-fraction {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write s, "-3.4"
  var x/xmm1: float <- parse-float-decimal s
  var expected-f/xmm0: float <- rational -0x22/-34, 0xa/10
  compare x, expected-f
  {
    break-if-=
    draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-fraction", 3/fg 0/bg
    move-cursor-to-left-margin-of-next-line 0/screen
    count-test-failure
  }
  draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg
}
pan class="w"> XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-xbm", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-xbitmap", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-png", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-rgb", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-tiff", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/jpeg", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("video/mpeg", "mpeg_play %s &", 1.0, 3.0, 0.0, 0); } #endif #ifdef EXEC_SCRIPTS /* set quality to 999.0 for protected exec applications */ #ifndef VMS HTSetPresentation("application/x-csh", "csh %s", 999.0, 3.0, 0.0, 0); HTSetPresentation("application/x-sh", "sh %s", 999.0, 3.0, 0.0, 0); HTSetPresentation("application/x-ksh", "ksh %s", 999.0, 3.0, 0.0, 0); #else HTSetPresentation("application/x-VMS_script", "@%s", 999.0, 3.0, 0.0, 0); #endif /* not VMS */ #endif /* EXEC_SCRIPTS */ /* * Add our header handlers. */ HTSetConversion("www/mime", "www/present", HTMIMEConvert, 1.0, 0.0, 0.0, 0); HTSetConversion("www/mime", "www/download", HTMIMEConvert, 1.0, 0.0, 0.0, 0); HTSetConversion("www/mime", "www/source", HTMIMEConvert, 1.0, 0.0, 0.0, 0); HTSetConversion("www/mime", "www/dump", HTMIMEConvert, 1.0, 0.0, 0.0, 0); /* * Add our compressed file handlers. */ HTSetConversion("www/compressed", "www/present", HTCompressed, 1.0, 0.0, 0.0, 0); HTSetConversion("www/compressed", "www/download", HTCompressed, 1.0, 0.0, 0.0, 0); HTSetConversion("www/compressed", "www/present", HTCompressed, 1.0, 0.0, 0.0, 0); HTSetConversion("www/compressed", "www/source", HTCompressed, 1.0, 0.0, 0.0, 0); HTSetConversion("www/compressed", "www/dump", HTCompressed, 1.0, 0.0, 0.0, 0); /* * Added the following to support some content types beginning to surface. */ HTSetConversion("application/html", "text/x-c", HTMLToC, 0.5, 0.0, 0.0, 0); HTSetConversion("application/html", "text/plain", HTMLToPlain, 0.5, 0.0, 0.0, 0); HTSetConversion("application/html", "www/present", HTMLPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("application/html", "www/source", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("application/x-wais-source", "www/source", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("application/x-wais-source", "www/present", HTWSRCConvert, 1.0, 0.0, 0.0, 0); HTSetConversion("application/x-wais-source", "www/download", HTWSRCConvert, 1.0, 0.0, 0.0, 0); HTSetConversion("application/x-wais-source", "www/dump", HTWSRCConvert, 1.0, 0.0, 0.0, 0); /* * Save all unknown mime types to disk. */ HTSetConversion("www/source", "www/present", HTSaveToFile, 1.0, 3.0, 0.0, 0); HTSetConversion("www/source", "www/source", HTSaveToFile, 1.0, 3.0, 0.0, 0); HTSetConversion("www/source", "www/download", HTSaveToFile, 1.0, 3.0, 0.0, 0); HTSetConversion("www/source", "*", HTSaveToFile, 1.0, 3.0, 0.0, 0); /* * Output all www/dump presentations to stdout. */ HTSetConversion("www/source", "www/dump", HTDumpToStdout, 1.0, 3.0, 0.0, 0); /* * Now add our basic conversions. */ HTSetConversion("text/x-sgml", "www/source", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/x-sgml", "www/present", HTMLPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/sgml", "www/source", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/sgml", "www/present", HTMLPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/plain","www/present", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/html", "www/source", HTPlainPresent, 1.0, 0.0, 0.0, 0); HTSetConversion("text/html", "text/x-c", HTMLToC, 0.5, 0.0, 0.0, 0); HTSetConversion("text/html", "text/plain", HTMLToPlain, 0.5, 0.0, 0.0, 0); HTSetConversion("text/html", "www/present", HTMLPresent, 1.0, 0.0, 0.0, 0); /* * These should override the default types as necessary. */ HTLoadTypesConfigFile(global_type_map); /* * Load the local maps. */ if ((fp = fopen(personal_type_map,"r")) != NULL) { fclose(fp); /* These should override everything else. */ HTLoadTypesConfigFile(personal_type_map); } else { char buffer[256]; #ifdef VMS sprintf(buffer, "sys$login:%s", personal_type_map); #else sprintf(buffer, "%s/%s", (Home_Dir() ? Home_Dir() : ""), personal_type_map); #endif HTLoadTypesConfigFile(buffer); } } /* Some of the following is taken from: */ /* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore) Permission to use, copy, modify, and distribute this material for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and that the name of Bellcore not be used in advertising or publicity pertaining to this material without the specific, prior written permission of an authorized representative of Bellcore. BELLCORE MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. */ /****************************************************** Metamail -- A tool to help diverse mail readers cope with diverse multimedia mail formats. Author: Nathaniel S. Borenstein, Bellcore ******************************************************* */ struct MailcapEntry { char *contenttype; char *command; char *testcommand; int needsterminal; int copiousoutput; int needtofree; char *label; char *printcommand; float quality; long int maxbytes; }; PRIVATE int ExitWithError PARAMS((char *txt)); PRIVATE int PassesTest PARAMS((struct MailcapEntry *mc)); #define LINE_BUF_SIZE 2000 #define TMPFILE_NAME_SIZE 127 PRIVATE char *GetCommand ARGS2(char *,s, char **,t) { char *s2; int quoted = 0; /* marca -- added + 1 for error case -- oct 24, 1993. */ s2 = malloc(strlen(s)*2 + 1); /* absolute max, if all % signs */ if (!s2) ExitWithError("Out of memory"); *t = s2; while (s && *s) { if (quoted) { if (*s == '%') *s2++ = '%'; /* Quote through next level, ugh! */ *s2++ = *s++; quoted = 0; } else { if (*s == ';') { *s2 = 0; return(++s); } if (*s == '\\') { quoted = 1; ++s; } else { *s2++ = *s++; } } } *s2 = 0; return(NULL); } /* no leading or trailing space, all lower case */ PRIVATE char *Cleanse ARGS1(char *,s) { char *tmp, *news; /* strip leading white space */ while (*s && isspace((unsigned char) *s)) ++s; news = s; /* put in lower case */ for (tmp=s; *tmp; ++tmp) { *tmp = TOLOWER ((unsigned char)*tmp); } /* strip trailing white space */ while (*--tmp && isspace((unsigned char) *tmp)) *tmp = 0; return(news); } PRIVATE int ProcessMailcapEntry ARGS2(FILE *,fp, struct MailcapEntry *,mc) { int i, j; size_t rawentryalloc = 2000; size_t len; char *rawentry, *s, *t, *LineBuf; LineBuf = malloc(LINE_BUF_SIZE); if (!LineBuf) ExitWithError("Out of memory"); rawentry = malloc(1 + rawentryalloc); if (!rawentry) ExitWithError("Out of memory"); *rawentry = 0; while (fgets(LineBuf, LINE_BUF_SIZE, fp)) { if (LineBuf[0] == '#') continue; len = strlen(LineBuf); if (len == 0) continue; if (LineBuf[len-1] == '\n') LineBuf[--len] = 0; if ((len + strlen(rawentry)) > rawentryalloc) { rawentryalloc += 2000; rawentry = realloc(rawentry, rawentryalloc+1); if (!rawentry) ExitWithError("Out of memory"); } if (len > 0 && LineBuf[len-1] == '\\') { LineBuf[len-1] = 0; strcat(rawentry, LineBuf); } else { strcat(rawentry, LineBuf); break; } } FREE(LineBuf); for (s = rawentry; *s && isspace((unsigned char) *s); ++s) ; if (!*s) { /* totally blank entry -- quietly ignore */ FREE(rawentry); return(0); } s = strchr(rawentry, ';'); if (s == NULL) { if (TRACE) { fprintf(stderr, "metamail: Ignoring invalid mailcap entry: %s\n", rawentry); } FREE(rawentry); return(0); } *s++ = 0; if (!strncasecomp(rawentry, "text/html", 9) || !strncasecomp(rawentry, "text/plain", 10)) { --s; *s = ';'; if (TRACE) { fprintf(stderr, "metamail: Ignoring mailcap entry: %s\n", rawentry); } FREE(rawentry); return(0); } for (i = 0, j = 0; rawentry[i]; i++) { if (rawentry[i] != ' ') { rawentry[j++] = TOLOWER(rawentry[i]); } } rawentry[j] = '\0'; mc->needsterminal = 0; mc->copiousoutput = 0; mc->needtofree = 1; mc->testcommand = NULL; mc->label = NULL; mc->printcommand = NULL; mc->contenttype = malloc(1+strlen(rawentry)); if (!mc->contenttype) ExitWithError("Out of memory"); strcpy(mc->contenttype, rawentry); mc->quality = 1.0; mc->maxbytes = 0; t = GetCommand(s, &mc->command); if (!t) { goto assign_presentation; } s = t; while (s && *s && isspace((unsigned char) *s)) ++s; while (s) { char *arg, *eq, *mallocd_string; t = GetCommand(s, &mallocd_string); arg = mallocd_string; eq = strchr(arg, '='); if (eq) *eq++ = 0; if (arg && *arg) { arg = Cleanse(arg); if (!strcmp(arg, "needsterminal")) { mc->needsterminal = 1; } else if (!strcmp(arg, "copiousoutput")) { mc->copiousoutput = 1; } else if (eq && !strcmp(arg, "test")) { mc->testcommand = NULL; StrAllocCopy(mc->testcommand, eq); if (TRACE) fprintf(stderr, "[HTInit]: found testcommand:%s\n", mc->testcommand); } else if (eq && !strcmp(arg, "description")) { mc->label = eq; } else if (eq && !strcmp(arg, "label")) { mc->label = eq; /* bogus old name for description */ } else if (eq && !strcmp(arg, "print")) { mc->printcommand = eq; } else if (eq && !strcmp(arg, "textualnewlines")) { /* no support for now. What does this do anyways? */ /* ExceptionalNewline(mc->contenttype, atoi(eq)); */ } else if (eq && !strcmp(arg, "q")) { mc->quality = atof(eq); if (mc->quality > 0.000 && mc->quality < 0.001) mc->quality = 0.001; } else if (eq && !strcmp(arg, "mxb")) { mc->maxbytes = atol(eq); if (mc->maxbytes < 0) mc->maxbytes = 0; } else if (strcmp(arg, "notes")) { /* IGNORE notes field */ if (*arg && TRACE) fprintf(stderr, "metamail: Ignoring mailcap flag: %s\n", arg); } } FREE(mallocd_string); s = t; } assign_presentation: FREE(rawentry); if (PassesTest(mc)) { if (TRACE) fprintf(stderr, "[HTInit] Setting up conversion %s : %s\n", mc->contenttype, mc->command); HTSetPresentation(mc->contenttype, mc->command, mc->quality, 3.0, 0.0, mc->maxbytes); } FREE(mc->command); FREE(mc->contenttype); return(1); } PRIVATE void BuildCommand ARGS3(char *,Buf, char *,controlstring, char *,TmpFileName) { char *from, *to; int prefixed = 0; for (from = controlstring, to = Buf; *from != '\0'; from++) { if (prefixed) { prefixed = 0; switch(*from) { case '%': *to++ = '%'; break; case 'n': case 'F': if (TRACE) { fprintf(stderr, "metamail: Bad mailcap \"test\" clause: %s\n", controlstring); } case 's': if (TmpFileName) { strcpy(to, TmpFileName); to += strlen(TmpFileName); } break; default: if (TRACE) { fprintf(stderr, "Ignoring unrecognized format code in mailcap file: %%%c\n", *from); } break; } } else if (*from == '%') { prefixed = 1; } else { *to++ = *from; } } *to = 0; } PRIVATE int PassesTest ARGS1(struct MailcapEntry *,mc) { int result; char *cmd, TmpFileName[TMPFILE_NAME_SIZE]; char *cp = NULL; /* * Make sure we have a command */ if (!mc->testcommand) return(1); /* * Save overhead of system() calls by faking these. - FM */ if (0 == strcasecomp(mc->testcommand, "test -n \"$DISPLAY\"")) { FREE(mc->testcommand); if (TRACE) fprintf(stderr,"Testing for XWINDOWS environment.\n"); if ((cp = getenv(DISPLAY)) != NULL && *cp != '\0') { if (TRACE) fprintf(stderr,"[HTInit] Test passed!\n"); return(0 == 0); } else { if (TRACE) fprintf(stderr,"[HTInit] Test failed!\n"); return(-1 == 0); } } if (0 == strcasecomp(mc->testcommand, "test -z \"$DISPLAY\"")) { FREE(mc->testcommand); if (TRACE) fprintf(stderr,"Testing for NON_XWINDOWS environment.\n"); if (!((cp = getenv(DISPLAY)) != NULL && *cp != '\0')) { if (TRACE) fprintf(stderr,"[HTInit] Test passed!\n"); return(0 == 0); } else { if (TRACE) fprintf(stderr,"[HTInit] Test failed!\n"); return(-1 == 0); } } /* * Why do anything but return success for this one! - FM */ if (0 == strcasecomp(mc->testcommand, "test -n \"$LYNX_VERSION\"")){ FREE(mc->testcommand); if (TRACE) { fprintf(stderr,"Testing for LYNX environment.\n"); fprintf(stderr,"[HTInit] Test passed!\n"); } return(0 == 0); } else /* * ... or failure for this one! - FM */ if (0 == strcasecomp(mc->testcommand, "test -z \"$LYNX_VERSION\"")) { FREE(mc->testcommand); if (TRACE) { fprintf(stderr,"Testing for non-LYNX environment.\n"); fprintf(stderr,"[HTInit] Test failed!\n"); } return(-1 == 0); } /* * Build the command and execute it. */ tempname(TmpFileName, NEW_FILE); cmd = (char *)malloc(1024); if (!cmd) ExitWithError("Out of memory"); BuildCommand(cmd, mc->testcommand, TmpFileName); if (TRACE) fprintf(stderr,"Executing test command: %s\n", cmd); result = system(cmd); FREE(cmd); /* * Free the test command as well since * we wont be needing it anymore. */ FREE(mc->testcommand); if (TRACE && result) fprintf(stderr,"[HTInit] Test failed!\n"); else if (TRACE) fprintf(stderr,"[HTInit] Test passed!\n"); return(result == 0); } PRIVATE int ProcessMailcapFile ARGS1(char *,file) { struct MailcapEntry mc; FILE *fp; if (TRACE) fprintf (stderr, "Loading types config file '%s'\n", file); if ((fp = fopen(file, "r")) == NULL) { if (TRACE) fprintf (stderr, "Could not open types config file '%s'\n",file); return(-1 == 0); } while (fp && !feof(fp)) { ProcessMailcapEntry(fp, &mc); } fclose(fp); return(0 == 0); } PRIVATE int ExitWithError ARGS1(char *,txt) { if (txt) fprintf(stderr, "metamail: %s\n", txt); #ifndef NOSIGHUP (void) signal(SIGHUP, SIG_DFL); #endif /* NOSIGHUP */ (void) signal(SIGTERM, SIG_DFL); #ifndef VMS (void) signal(SIGINT, SIG_DFL); #endif /* !VMS */ #ifdef SIGTSTP if (no_suspend) (void) signal(SIGTSTP,SIG_DFL); #endif /* SIGTSTP */ exit(-1); return(-1); } PRIVATE int HTLoadTypesConfigFile ARGS1(char *,fn) { return ProcessMailcapFile(fn); } /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ /* Define a basic set of suffixes ** ------------------------------ ** ** The LAST suffix for a type is that used for temporary files ** of that type. ** The quality is an apriori bias as to whether the file should be ** used. Not that different suffixes can be used to represent files ** which are of the same format but are originals or regenerated, ** with different values. */ PUBLIC void HTFileInit NOARGS { FILE *fp; extern char *global_extension_map; extern char *personal_extension_map; if (TRACE) fprintf (stderr, "@@@ Using default extension map\n"); /* default suffix interpretation */ HTSetSuffix("*", "text/plain", "7bit", 1.0); HTSetSuffix("*.*", "text/plain", "7bit", 1.0); #ifdef EXEC_SCRIPTS /* * define these extentions for exec scripts. */ #ifndef VMS /* for csh exec links */ HTSetSuffix(".csh", "application/x-csh", "8bit", 0.8); HTSetSuffix(".sh", "application/x-sh", "8bit", 0.8); HTSetSuffix(".ksh", "application/x-ksh", "8bit", 0.8); #else HTSetSuffix(".com", "application/x-VMS_script", "8bit", 0.8); #endif /* !VMS */ #endif /* EXEC_SCRIPTS */ HTSetSuffix(".saveme", "application/x-Binary", "binary", 1.0); HTSetSuffix(".dump", "application/x-Binary", "binary", 1.0); HTSetSuffix(".bin", "application/x-Binary", "binary", 1.0); HTSetSuffix(".arc", "application/x-Compressed", "binary", 1.0); HTSetSuffix(".alpha-exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".alpha_exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".AXP-exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".AXP_exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".VAX-exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".VAX_exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".exe", "application/x-Executable", "binary", 1.0); HTSetSuffix(".exe.Z", "application/x-Comp. Executable", "binary", 1.0); HTSetSuffix(".Z", "application/UNIX Compressed", "binary", 1.0); HTSetSuffix(".tar_Z", "application/UNIX Compr. Tar", "binary", 1.0); HTSetSuffix(".tar.Z", "application/UNIX Compr. Tar", "binary", 1.0); HTSetSuffix("-gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix("_gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix(".gz", "application/GNU Compressed", "binary", 1.0); HTSetSuffix(".tar.gz", "application/GNU Compr. Tar", "binary", 1.0); HTSetSuffix(".tgz", "application/GNU Compr. Tar", "binary", 1.0); HTSetSuffix(".src", "application/x-WAIS-source", "8bit", 1.0); HTSetSuffix(".wsrc", "application/x-WAIS-source", "8bit", 1.0); HTSetSuffix(".zip", "application/x-Zip File", "binary", 1.0); HTSetSuffix(".uu", "application/x-UUencoded", "8bit", 1.0); HTSetSuffix(".hqx", "application/x-Binhex", "8bit", 1.0); HTSetSuffix(".o", "application/x-Prog. Object", "binary", 1.0); HTSetSuffix(".a", "application/x-Prog. Library", "binary", 1.0); HTSetSuffix(".oda", "application/ODA", "binary", 1.0); HTSetSuffix(".pdf", "application/PDF", "binary", 1.0); HTSetSuffix(".eps", "application/Postscript", "8bit", 1.0); HTSetSuffix(".ai", "application/Postscript", "8bit", 1.0); HTSetSuffix(".ps", "application/Postscript", "8bit", 1.0); HTSetSuffix(".rtf", "application/RTF", "8bit", 1.0); HTSetSuffix(".dvi", "application/x-DVI", "8bit", 1.0); HTSetSuffix(".hdf", "application/x-HDF", "8bit", 1.0); HTSetSuffix(".cdf", "application/x-netcdf", "8bit", 1.0); HTSetSuffix(".nc", "application/x-netcdf", "8bit", 1.0); HTSetSuffix(".latex", "application/x-Latex", "8bit", 1.0); HTSetSuffix(".tex", "application/x-Tex", "8bit", 1.0); HTSetSuffix(".texinfo", "application/x-Texinfo", "8bit", 1.0); HTSetSuffix(".texi", "application/x-Texinfo", "8bit", 1.0); HTSetSuffix(".t", "application/x-Troff", "8bit", 1.0); HTSetSuffix(".tr", "application/x-Troff", "8bit", 1.0); HTSetSuffix(".roff", "application/x-Troff", "8bit", 1.0); HTSetSuffix(".man", "application/x-Troff-man", "8bit", 1.0); HTSetSuffix(".me", "application/x-Troff-me", "8bit", 1.0); HTSetSuffix(".ms", "application/x-Troff-ms", "8bit", 1.0); HTSetSuffix(".zoo", "application/x-Zoo File", "binary", 1.0); HTSetSuffix(".bak", "application/x-VMS BAK File", "binary", 1.0); HTSetSuffix(".bkp", "application/x-VMS BAK File", "binary", 1.0); HTSetSuffix(".bck", "application/x-VMS BAK File", "binary", 1.0); HTSetSuffix(".bkp_gz", "application/x-GNU BAK File", "binary", 1.0); HTSetSuffix(".bkp-gz", "application/x-GNU BAK File", "binary", 1.0); HTSetSuffix(".bck_gz", "application/x-GNU BAK File", "binary", 1.0); HTSetSuffix(".bck-gz", "application/x-GNU BAK File", "binary", 1.0); HTSetSuffix(".bkp-Z", "application/x-Comp. BAK File", "binary", 1.0); HTSetSuffix(".bkp_Z", "application/x-Comp. BAK File", "binary", 1.0); HTSetSuffix(".bck-Z", "application/x-Comp. BAK File", "binary", 1.0); HTSetSuffix(".bck_Z", "application/x-Comp. BAK File", "binary", 1.0); HTSetSuffix(".hlb", "application/x-VMS Help Libr.", "binary", 1.0); HTSetSuffix(".olb", "application/x-VMS Obj. Libr.", "binary", 1.0); HTSetSuffix(".tlb", "application/x-VMS Text Libr.", "binary", 1.0); HTSetSuffix(".obj", "application/x-VMS Prog. Obj.", "binary", 1.0); HTSetSuffix(".decw$book", "application/x-DEC BookReader", "binary", 1.0); HTSetSuffix(".mem", "application/x-RUNOFF-MANUAL", "8bit", 1.0); HTSetSuffix(".vsd", "application/visio", "binary", 1.0); HTSetSuffix(".lha", "application/x-lha File", "binary", 1.0); HTSetSuffix(".lzh", "application/x-lzh File", "binary", 1.0); HTSetSuffix(".sea", "application/x-sea File", "binary", 1.0); HTSetSuffix(".sit", "application/x-sit File", "binary", 1.0); HTSetSuffix(".dms", "application/x-dms File", "binary", 1.0); HTSetSuffix(".iff", "application/x-iff File", "binary", 1.0); HTSetSuffix(".bcpio", "application/x-bcpio", "binary", 1.0); HTSetSuffix(".cpio", "application/x-cpio", "binary", 1.0); HTSetSuffix(".gtar", "application/x-gtar", "binary", 1.0); HTSetSuffix(".shar", "application/x-shar", "8bit", 1.0); HTSetSuffix(".share", "application/x-share", "8bit", 1.0); HTSetSuffix(".sh", "application/x-sh", "8bit", 1.0); /* xtra */ HTSetSuffix(".sv4cpio", "application/x-sv4cpio", "binary", 1.0); HTSetSuffix(".sv4crc", "application/x-sv4crc", "binary", 1.0); HTSetSuffix(".tar", "application/x-Tar File", "binary", 1.0); HTSetSuffix(".ustar", "application/x-ustar", "binary", 1.0); HTSetSuffix(".snd", "audio/basic", "binary", 1.0); HTSetSuffix(".au", "audio/basic", "binary", 1.0); HTSetSuffix(".aifc", "audio/x-aiff", "binary", 1.0); HTSetSuffix(".aif", "audio/x-aiff", "binary", 1.0); HTSetSuffix(".aiff", "audio/x-aiff", "binary", 1.0); HTSetSuffix(".wav", "audio/x-wav", "binary", 1.0); HTSetSuffix(".midi", "audio/midi", "binary", 1.0); HTSetSuffix(".mod", "audio/mod", "binary", 1.0); HTSetSuffix(".gif", "image/gif", "binary", 1.0); HTSetSuffix(".ief", "image/ief", "binary", 1.0); HTSetSuffix(".jfif", "image/jpeg", "binary", 1.0); /* xtra */ HTSetSuffix(".jfif-tbnl", "image/jpeg", "binary", 1.0); /* xtra */ HTSetSuffix(".jpe", "image/jpeg", "binary", 1.0); HTSetSuffix(".jpg", "image/jpeg", "binary", 1.0); HTSetSuffix(".jpeg", "image/jpeg", "binary", 1.0); HTSetSuffix(".tif", "image/tiff", "binary", 1.0); HTSetSuffix(".tiff", "image/tiff", "binary", 1.0); HTSetSuffix(".ham", "image/ham", "binary", 1.0); HTSetSuffix(".ras", "image/x-cmu-rast", "binary", 1.0); HTSetSuffix(".pnm", "image/x-portable-anymap", "binary", 1.0); HTSetSuffix(".pbm", "image/x-portable-bitmap", "binary", 1.0); HTSetSuffix(".pgm", "image/x-portable-graymap", "binary", 1.0); HTSetSuffix(".ppm", "image/x-portable-pixmap", "binary", 1.0); HTSetSuffix(".png", "image/x-png", "binary", 1.0); HTSetSuffix(".rgb", "image/x-rgb", "binary", 1.0); HTSetSuffix(".xbm", "image/x-xbitmap", "binary", 1.0); HTSetSuffix(".xpm", "image/x-xpixmap", "binary", 1.0); HTSetSuffix(".xwd", "image/x-xwindowdump", "binary", 1.0); HTSetSuffix(".rtx", "text/richtext", "8bit", 1.0); HTSetSuffix(".tsv", "text/tab-separated-values", "8bit", 1.0); HTSetSuffix(".etx", "text/x-setext", "8bit", 1.0); HTSetSuffix(".mpg", "video/mpeg", "binary", 1.0); HTSetSuffix(".mpe", "video/mpeg", "binary", 1.0); HTSetSuffix(".mpeg", "video/mpeg", "binary", 1.0); HTSetSuffix(".mov", "video/quicktime", "binary", 1.0); HTSetSuffix(".qt", "video/quicktime", "binary", 1.0); HTSetSuffix(".avi", "video/x-msvideo", "binary", 1.0); HTSetSuffix(".movie", "video/x-sgi-movie", "binary", 1.0); HTSetSuffix(".mv", "video/x-sgi-movie", "binary", 1.0); HTSetSuffix(".mime", "message/rfc822", "8bit", 1.0); HTSetSuffix(".c", "text/plain", "8bit", 1.0); HTSetSuffix(".cc", "text/plain", "8bit", 1.0); HTSetSuffix(".c++", "text/plain", "8bit", 1.0); HTSetSuffix(".h", "text/plain", "8bit", 1.0); HTSetSuffix(".pl", "text/plain", "8bit", 1.0); HTSetSuffix(".text", "text/plain", "8bit", 1.0); HTSetSuffix(".txt", "text/plain", "8bit", 1.0); HTSetSuffix(".htm", "text/html", "8bit", 1.0); HTSetSuffix(".html3", "text/html", "8bit", 1.0); HTSetSuffix(".ht3", "text/html", "8bit", 1.0); HTSetSuffix(".shtml", "text/html", "8bit", 1.0); HTSetSuffix(".htmlx", "text/html", "8bit", 1.0); HTSetSuffix(".html", "text/html", "8bit", 1.0); /* These should override the default extensions as necessary. */ HTLoadExtensionsConfigFile(global_extension_map); if ((fp = fopen(personal_extension_map,"r")) != NULL) { fclose(fp); /* These should override everything else. */ HTLoadExtensionsConfigFile(personal_extension_map); } else { char buffer[256]; #ifdef VMS sprintf(buffer, "sys$login:%s", personal_extension_map); #else sprintf(buffer, "%s/%s", (Home_Dir() ? Home_Dir() : ""), personal_extension_map); #endif /* VMS */ /* These should override everything else. */ HTLoadExtensionsConfigFile(buffer); } } /* -------------------- Extension config file reading --------------------- */ /* The following is lifted from NCSA httpd 1.0a1, by Rob McCool; NCSA httpd is in the public domain, as is this code. */ #define MAX_STRING_LEN 256 PRIVATE int HTGetLine ARGS3(char *,s, int,n, FILE *,f) { register int i = 0; if (!f) return(1); while (1) { s[i] = (char)fgetc(f); if (s[i] == CR) s[i] = fgetc(f); if ((s[i] == EOF) || (s[i] == LF) || (i == (n-1))) { s[i] = '\0'; return (feof(f) ? 1 : 0); } ++i; } } PRIVATE void HTGetWord ARGS4(char *,word, char *,line, char ,stop, char ,stop2) { int x = 0, y; for (x = 0; line[x] && line[x] != stop && line[x] != stop2; x++) { word[x] = line[x]; } word[x] = '\0'; if (line[x]) ++x; y=0; while ((line[y++] = line[x++])) ; return; } PRIVATE int HTLoadExtensionsConfigFile ARGS1(char *,fn) { char l[MAX_STRING_LEN],w[MAX_STRING_LEN],*ct; FILE *f; int x, count = 0; if (TRACE) fprintf (stderr, "Loading extensions config file '%s'\n", fn); if ((f = fopen(fn,"r")) == NULL) { if (TRACE) fprintf(stderr, "Could not open extensions config file '%s'\n",fn); return count; } while (!(HTGetLine(l,MAX_STRING_LEN,f))) { HTGetWord(w, l, ' ', '\t'); if (l[0] == '\0' || w[0] == '#') continue; ct = (char *)malloc(sizeof(char) * (strlen(w) + 1)); if (!ct) outofmem(__FILE__, "HTLoadExtensionsConfigFile"); strcpy(ct,w); for (x = 0; ct[x]; x++) ct[x] = TOLOWER(ct[x]); while(l[0]) { HTGetWord(w, l, ' ', '\t'); if (w[0] && (w[0] != ' ')) { char *ext = (char *)malloc(sizeof(char) * (strlen(w)+1+1)); if (!ct) outofmem(__FILE__, "HTLoadExtensionsConfigFile"); for (x = 0; w[x]; x++) ext[x+1] = TOLOWER(w[x]); ext[0] = '.'; ext[strlen(w)+1] = 0; if (TRACE) fprintf (stderr, "SETTING SUFFIX '%s' to '%s'\n", ext, ct); if (strstr(ct, "tex") != NULL || strstr(ct, "postscript") != NULL || strstr(ct, "sh") != NULL || strstr(ct, "troff") != NULL || strstr(ct, "rtf") != NULL) HTSetSuffix (ext, ct, "8bit", 1.0); else HTSetSuffix (ext, ct, "binary", 1.0); count++; FREE(ext); } } FREE(ct); } fclose(f); return count; }