1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

More work on the JS end-user deliverables. Add tool/stripccomments.c to support that.

FossilOrigin-Name: 2156f0744acfe425457430a0f6a7e02de907de85edba81a6d4eef40293e561c8
This commit is contained in:
stephan
2022-10-18 20:36:50 +00:00
parent ac79fa1c78
commit b5e2e6fcd3
6 changed files with 331 additions and 40 deletions

View File

@@ -1,11 +1,29 @@
######################################################################## ########################################################################
# This GNU makefile drives the build of the sqlite3 WASM # This GNU makefile drives the build of the sqlite3 WASM
# components. It is not part of the canonical build process. # components. It is not part of the canonical build process.
#
# This build assumes a Linux platform and is not intended for
# client-level use. It is for the sqlite project's own development of
# the JS/WASM components.
#
# Primary targets:
#
# default, all = build in dev mode
#
# o0, o1, o2, o3, os, oz = full clean/rebuild with the -Ox level indicated
# by the target name. Rebuild is necessary for all components to get
# the desired optimization level.
#
# dist = create end user deliverables. Add dist-opt=oX to build with a
# specific optimization level, where oX is one of the above-listed
# o? target names.
#
# clean = clean up
######################################################################## ########################################################################
SHELL := $(shell which bash 2>/dev/null) SHELL := $(shell which bash 2>/dev/null)
MAKEFILE := $(lastword $(MAKEFILE_LIST)) MAKEFILE := $(lastword $(MAKEFILE_LIST))
all: default: all
release: all release: default
# Emscripten SDK home dir and related binaries... # Emscripten SDK home dir and related binaries...
EMSDK_HOME ?= $(word 1,$(wildcard $(HOME)/src/emsdk $(HOME)/emsdk)) EMSDK_HOME ?= $(word 1,$(wildcard $(HOME)/src/emsdk $(HOME)/emsdk))
@@ -46,7 +64,9 @@ dir.api := api
dir.jacc := jaccwabyt dir.jacc := jaccwabyt
dir.common := common dir.common := common
dir.fiddle := fiddle dir.fiddle := fiddle
dir.tool := $(dir.top)/tool
CLEAN_FILES := *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~ CLEAN_FILES := *~ $(dir.jacc)/*~ $(dir.api)/*~ $(dir.common)/*~
DISTCLEAN_FILES := ./-dummy
emcc_enable_bigint ?= 1 emcc_enable_bigint ?= 1
sqlite3.c := $(dir.top)/sqlite3.c sqlite3.c := $(dir.top)/sqlite3.c
sqlite3.h := $(dir.top)/sqlite3.h sqlite3.h := $(dir.top)/sqlite3.h
@@ -113,8 +133,11 @@ emcc_opt_full := $(emcc_opt) -g3
$(sqlite3.c) $(sqlite3.h): $(sqlite3.c) $(sqlite3.h):
$(MAKE) -C $(dir.top) sqlite3.c $(MAKE) -C $(dir.top) sqlite3.c
.PHONY: clean distclean
clean: clean:
-rm -f $(CLEAN_FILES) -rm -f $(CLEAN_FILES)
distclean: clean
-rm -f $(DISTCLEAN_FILES)
ifeq (release,$(filter release,$(MAKECMDGOALS))) ifeq (release,$(filter release,$(MAKECMDGOALS)))
ifeq (,$(wasm-strip)) ifeq (,$(wasm-strip))
@@ -128,7 +151,12 @@ endif
version-info := $(dir.wasm)/version-info version-info := $(dir.wasm)/version-info
$(version-info): $(dir.wasm)/version-info.c $(sqlite3.h) $(MAKEFILE) $(version-info): $(dir.wasm)/version-info.c $(sqlite3.h) $(MAKEFILE)
$(CC) -O0 -I$(dir.top) -o $@ $< $(CC) -O0 -I$(dir.top) -o $@ $<
CLEAN_FILES := $(version-info) DISTCLEAN_FILES += $(version-info)
stripccomments := $(dir.tool)/stripccomments
$(stripccomments): $(stripccomments).c $(MAKEFILE)
$(CC) -o $@ $<
DISTCLEAN_FILES += $(stripccomments)
EXPORTED_FUNCTIONS.api.in := $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api EXPORTED_FUNCTIONS.api.in := $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api
@@ -480,11 +508,7 @@ push-fiddle: $(fiddle_files)
# painful. # painful.
.PHONY: o0 o1 o2 o3 os oz .PHONY: o0 o1 o2 o3 os oz
o-xtra := -g3 o-xtra := -flto
# ^^^ -g3 is important to keep higher -O levels from mangling (via
# minification), or outright removing, otherwise working code.
o-xtra += -flto
# ^^^^ -flto can have a considerably performance boost at -O0 but # ^^^^ -flto can have a considerably performance boost at -O0 but
# doubles the build time and seems to have negligible effect on # doubles the build time and seems to have negligible effect on
# higher optimization levels. # higher optimization levels.
@@ -515,7 +539,9 @@ PLATFORMS_WITH_NO_WASMFS := aarch64 # add any others here
THIS_ARCH := $(shell /usr/bin/uname -m) THIS_ARCH := $(shell /usr/bin/uname -m)
ifneq (,$(filter $(THIS_ARCH),$(PLATFORMS_WITH_NO_WASMFS))) ifneq (,$(filter $(THIS_ARCH),$(PLATFORMS_WITH_NO_WASMFS)))
$(info This platform does not support the WASMFS build.) $(info This platform does not support the WASMFS build.)
HAVE_WASMFS := 0
else else
HAVE_WASMFS := 1
include wasmfs.make include wasmfs.make
endif endif

View File

@@ -15,10 +15,10 @@ This archive contains two related deliverables:
but is less portable than the main build, so is provided but is less portable than the main build, so is provided
as a separate binary. as a separate binary.
Both directories contain small demonstration apps. Browsers will not Both directories contain small demonstration and test apps. Browsers
server WASM files from file:// URLs, so the demonstrations require a will not serve WASM files from file:// URLs, so the demo/test apps
web server and that server must include the following headers in its require a web server and that server must include the following
response when serving the files: headers in its response when serving the files:
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Embedder-Policy: require-corp

View File

@@ -9,51 +9,87 @@
####################################################################### #######################################################################
MAKEFILE.dist := $(lastword $(MAKEFILE_LIST)) MAKEFILE.dist := $(lastword $(MAKEFILE_LIST))
ifeq (0,$(HAVE_WASMFS))
$(error The 'dist' target needs to be run on a WASMFS-capable platform.)
endif
######################################################################## ########################################################################
# Chicken/egg situation: we need $(version-info) to get the version # Chicken/egg situation: we need $(version-info) to get the version
# info for the archive name, but that binary may not yet be built, so # info for the archive name, but that binary may not yet be built, and
# we have to use a temporary name for the archive. # won't be built until we expand the dependencies. We have to use a
# temporary name for the archive.
dist-name = sqlite-wasm-TEMP dist-name = sqlite-wasm-TEMP
dist-archive = $(dist-name).zip dist-archive = $(dist-name).zip
.PHONY: $(dist-archive)
CLEAN_FILES += $(wildcard sqlite-wasm-*.zip)
#ifeq (0,1) #ifeq (0,1)
# $(info WARNING *******************************************************************) # $(info WARNING *******************************************************************)
# $(info ** Be sure to create the desired build configuration before creating the) # $(info ** Be sure to create the desired build configuration before creating the)
# $(info ** distribution archive. Use one of the following targets to do so:) # $(info ** distribution archive. Use one of the following targets to do so:)
# $(info **)
# $(info ** o2: builds with -O2, resulting in the fastest builds) # $(info ** o2: builds with -O2, resulting in the fastest builds)
# $(info ** oz: builds with -Oz, resulting in the smallest builds) # $(info ** oz: builds with -Oz, resulting in the smallest builds)
# $(info /WARNING *******************************************************************) # $(info /WARNING *******************************************************************)
#endif #endif
########################################################################
# dist-opt must be the name of a target which triggers the
# build of the files to be packed into the dist archive. The
# intention is that it be one of (o0, o1, o2, o3, os, oz), each of
# which uses like-named -Ox optimization level flags. The o2 target
# provides the best overall runtime speeds. The oz target provides
# slightly slower speeds (roughly 10%) with significantly smaller WASM
# file sizes. Note that -O2 (the o2 target) results in faster binaries
# than both -O3 and -Os (the o3 and os targets) in all tests run to
# date.
dist-opt ?= oz
demo-123.html := $(dir.wasm)/demo-123.html demo-123.html := $(dir.wasm)/demo-123.html
demo-123-worker.html := $(dir.wasm)/demo-123-worker.html demo-123-worker.html := $(dir.wasm)/demo-123-worker.html
demo-123.js := $(dir.wasm)/demo-123.js demo-123.js := $(dir.wasm)/demo-123.js
demo-files := $(demo-123.js) $(demo-123.html) $(demo-123-worker.html) demo-files := $(demo-123.js) $(demo-123.html) $(demo-123-worker.html) \
tester1.html tester1.js tester1-worker.html
README-dist := $(dir.wasm)/README-dist.txt README-dist := $(dir.wasm)/README-dist.txt
$(dist-archive): $(sqlite3.wasm) $(sqlite3.js) $(sqlite3-wasmfs.wasm) $(sqlite3-wasmfs.js) dist-dir-main := $(dist-name)/main
#$(dist-archive): $(sqlite3.h) $(sqlite3.c) $(sqlite3-wasm.c) dist-dir-wasmfs := $(dist-name)/wasmfs
$(dist-archive): $(MAKEFILE.dist) $(version-info) $(demo-files) $(README-dist) ########################################################################
$(dist-archive): oz # $(dist-archive): create the end-user deliverable archive.
rm -fr $(dist-name) #
mkdir -p $(dist-name)/main $(dist-name)/wasmfs # Maintenance reminder: because $(dist-archive) depends on
cp -p $(README-dist) $(dist-name)/README.txt # $(dist-opt), and $(dist-opt) will depend on clean, having any deps
cp -p $(sqlite3.wasm) $(sqlite3.js) $(dist-name)/main # on $(dist-archive) which themselves may be cleaned up by the clean
cp -p $(demo-files) $(dist-name)/main # target will lead to grief in parallel builds (-j #). Thus
cp -p $(sqlite3-wasmfs.wasm) $(sqlite3-wasmfs.js) $(dist-name)/wasmfs # $(dist-target)'s deps must be trimmed to non-generated files or
for i in $(demo-123.js) $(demo-123.html); do \ # files which are _not_ cleaned up by the clean target.
$(dist-archive): \
$(stripccomments) $(version-info) \
$(dist-opt) \
$(MAKEFILE) $(MAKEFILE.dist)
@echo "Making end-user deliverables..."
@rm -fr $(dist-name)
@mkdir -p $(dist-dir-main) $(dist-dir-wasmfs)
@cp -p $(README-dist) $(dist-name)/README.txt
@cp -p $(sqlite3.wasm) $(dist-dir-main)
@$(stripccomments) -k -k < $(sqlite3.js) \
> $(dist-dir-main)/$(notdir $(sqlite3.js))
@cp -p $(demo-files) $(dist-dir-main)
@cp -p $(sqlite3-wasmfs.wasm) sqlite3-wasmfs.worker.js $(dist-dir-wasmfs)
@$(stripccomments) -k -k < $(sqlite3-wasmfs.js) \
> $(dist-dir-wasmfs)/$(notdir $(sqlite3-wasmfs.js))
@for i in $(demo-123.js) $(demo-123.html); do \
sed -e 's/\bsqlite3\.js\b/sqlite3-wasmfs.js/' $$i \ sed -e 's/\bsqlite3\.js\b/sqlite3-wasmfs.js/' $$i \
> $(dist-name)/wasmfs/$${i##*/} || exit; \ > $(dist-dir-wasmfs)/$${i##*/} || exit; \
done done
vnum=$$($(version-info) --version-number); \ @vnum=$$($(version-info) --version-number); \
vdir=sqlite-wasm-$$vnum; \ vdir=sqlite-wasm-$$vnum; \
arc=$$vdir.zip; \ arc=$$vdir.zip; \
echo "Making $$arc ..."; \
rm -f $$arc; \ rm -f $$arc; \
mv $(dist-name) $$vdir; \ mv $(dist-name) $$vdir; \
zip -qr $$arc $$vdir; \ zip -qr $$arc $$vdir; \
rm -fr $$vdir; \ rm -fr $$vdir; \
ls -la $$arc; \ ls -la $$arc; \
unzip -l $$arc unzip -lv $$arc || echo "Missing unzip app? Not fatal."
#$(shell $(version-info) --version-number) #$(shell $(version-info) --version-number)
dist: $(dist-archive) dist: $(dist-archive)

View File

@@ -1,5 +1,5 @@
C Add\snew\stest\sfile\swindowE.test,\sto\stest\sthe\swindow\sfunctions\smodules\sresponse\sto\san\sinconsistent\scollation\ssequence. C More\swork\son\sthe\sJS\send-user\sdeliverables.\sAdd\stool/stripccomments.c\sto\ssupport\sthat.
D 2022-10-18T15:02:08.725 D 2022-10-18T20:36:50.562
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -473,8 +473,8 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0 F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0
F ext/wasm/GNUmakefile 2fd83d7183bce3f9236fdd2dbe20a4ea37b1d7b26e1a422054ec63008319f065 F ext/wasm/GNUmakefile 279fd4589ba602e24d8e66ca795ec5a2275a0e329405e4e984e8ea0579339bae
F ext/wasm/README-dist.txt bc1fb4f90a28ad2ed0e555a637f393b9249d8d928ac509dad6293b7cae628ea4 F ext/wasm/README-dist.txt 170be2d47b4b52504ef09088ca2f143aab657de0f9ac04d3a68e366f40929c3d
F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066 F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 89983a8d122c35a90c65ec667844b95a78bcd04f3198a99c1e0c8368c1a0b03a F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 89983a8d122c35a90c65ec667844b95a78bcd04f3198a99c1e0c8368c1a0b03a
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
@@ -504,7 +504,7 @@ F ext/wasm/demo-123.html 7c239c9951d1b113f9f532969ac039294cf1dcfee2b3ae0a2c1ed2b
F ext/wasm/demo-123.js e0cbeb3495e14103763d5c49794a24d67cf3d78e0ed5b82843be70c0c2ee4b3b F ext/wasm/demo-123.js e0cbeb3495e14103763d5c49794a24d67cf3d78e0ed5b82843be70c0c2ee4b3b
F ext/wasm/demo-kvvfs1.html 7d4f28873de67f51ac18c584b7d920825139866a96049a49c424d6f5a0ea5e7f F ext/wasm/demo-kvvfs1.html 7d4f28873de67f51ac18c584b7d920825139866a96049a49c424d6f5a0ea5e7f
F ext/wasm/demo-kvvfs1.js 105596bd2ccd0b1deb5fde8e99b536e8242d4bb5932fac0c8403ff3a6bc547e8 F ext/wasm/demo-kvvfs1.js 105596bd2ccd0b1deb5fde8e99b536e8242d4bb5932fac0c8403ff3a6bc547e8
F ext/wasm/dist.make d7076e90f04396f1cc54cb41ee106451496179c10d54bbdebb65ae7b1ae12211 F ext/wasm/dist.make 1d59fafdfcf6fc5ee0f3351b21199585dba21afcf0518241789fd5d37a1c011d
F ext/wasm/fiddle.make b609dfde299b4523d7123b7e0cecaa1a0aff0dd984e62cea653aae91f5063c90 F ext/wasm/fiddle.make b609dfde299b4523d7123b7e0cecaa1a0aff0dd984e62cea653aae91f5063c90
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/fiddle/fiddle-worker.js 531859a471924a0ea48afa218e6877f0c164ca324d51e15843ed6ecc1c65c7ee F ext/wasm/fiddle/fiddle-worker.js 531859a471924a0ea48afa218e6877f0c164ca324d51e15843ed6ecc1c65c7ee
@@ -2007,6 +2007,7 @@ F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaa
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9 F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
@@ -2036,8 +2037,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 904b54625d985e742888e06ba792cab316b9ec9d6669d9cf509bac48030373ca P 740a2eb0928d54fdf735a8e573c6a61a34dbd295b46e5b6ef39e957fd2623293
R 609c010622cb8a1edf242ffa07ea33a0 R f3423b9e5fdd1b3c8749326c161b8bbf
U dan U stephan
Z 47ec91d5045ad14459bc2cd80292963b Z 8ed4b03e8c6243f1d25f4dc2d31715c7
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
740a2eb0928d54fdf735a8e573c6a61a34dbd295b46e5b6ef39e957fd2623293 2156f0744acfe425457430a0f6a7e02de907de85edba81a6d4eef40293e561c8

228
tool/stripccomments.c Normal file
View File

@@ -0,0 +1,228 @@
/**
Strips C- and C++-style comments from stdin, sending the results to
stdout. It assumes that its input is legal C-like code, and does
only little error handling.
It treats string literals as anything starting and ending with
matching double OR single quotes OR backticks (for use with
scripting languages which use those). It assumes that a quote
character within a string which uses the same quote type is escaped
by a backslash. It should not be used on any code which might
contain C/C++ comments inside heredocs, and similar constructs, as
it will strip those out.
Usage: $0 [--keep-first|-k] < input > output
The --keep-first (-k) flag tells it to retain the first comment in the
input stream (which is often a license or attribution block). It
may be given repeatedly, each one incrementing the number of
retained comments by one.
License: Public Domain
Author: Stephan Beal (stephan@wanderinghorse.net)
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#if 1
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:\t",__FILE__,__LINE__); \
printf pfexp; \
} while(0)
#else
#define MARKER(exp) if(0) printf
#endif
struct {
FILE * input;
FILE * output;
int rc;
int keepFirst;
} App = {
0/*input*/,
0/*output*/,
0/*rc*/,
0/*keepFirst*/
};
void do_it_all(void){
enum states {
S_NONE = 0 /* not in comment */,
S_SLASH1 = 1 /* slash - possibly comment prefix */,
S_CPP = 2 /* in C++ comment */,
S_C = 3 /* in C comment */
};
int ch, prev = EOF;
FILE * out = App.output;
int const slash = '/';
int const star = '*';
int line = 1;
int col = 0;
enum states state = S_NONE /* current state */;
int elide = 0 /* true if currently eliding output */;
int state3Col = -99
/* huge kludge for odd corner case: */
/*/ <--- here. state3Col marks the source column in which a C-style
comment starts, so that it can tell if star-slash inside a
C-style comment is the end of the comment or is the weird corner
case marked at the start of _this_ comment block. */;
for( ; EOF != (ch = fgetc(App.input)); prev = ch,
++col){
switch(state){
case S_NONE:
if('\''==ch || '"'==ch || '`'==ch){
/* Read string literal...
needed to properly catch comments in strings. */
int const quote = ch,
startLine = line, startCol = col;
int ch2, escaped = 0, endOfString = 0;
fputc(ch, out);
for( ++col; !endOfString && EOF != (ch2 = fgetc(App.input));
++col ){
switch(ch2){
case '\\': escaped = !escaped;
break;
case '`':
case '\'':
case '"':
if(!escaped && quote == ch2) endOfString = 1;
escaped = 0;
break;
default:
escaped = 0;
break;
}
if('\n'==ch2){
++line;
col = 0;
}
fputc(ch2, out);
}
if(EOF == ch2){
fprintf(stderr, "Unexpected EOF while reading %s literal "
"on line %d column %d.\n",
('\''==ch) ? "char" : "string",
startLine, startCol);
App.rc = 1;
return;
}
break;
}
else if(slash == ch){
/* MARKER(("state 0 ==> 1 @ %d:%d\n", line, col)); */
state = S_SLASH1;
break;
}
fputc(ch, out);
break;
case S_SLASH1: /* 1 slash */
/* MARKER(("SLASH1 @ %d:%d App.keepFirst=%d\n",
line, col, App.keepFirst)); */
switch(ch){
case '*':
/* Enter C comment */
if(App.keepFirst>0){
elide = 0;
--App.keepFirst;
}else{
elide = 1;
}
/*MARKER(("state 1 ==> 3 @ %d:%d\n", line, col));*/
state = S_C;
state3Col = col-1;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
break;
case '/':
/* Enter C++ comment */
if(App.keepFirst>0){
elide = 0;
--App.keepFirst;
}else{
elide = 1;
}
/*MARKER(("state 1 ==> 2 @ %d:%d\n", line, col));*/
state = S_CPP;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
break;
default:
/* It wasn't a comment after all. */
state = S_NONE;
if(!elide){
fputc(prev, out);
fputc(ch, out);
}
}
break;
case S_CPP: /* C++ comment */
if('\n' == ch){
/* MARKER(("state 2 ==> 0 @ %d:%d\n", line, col)); */
state = S_NONE;
elide = 0;
}
if(!elide){
fputc(ch, out);
}
break;
case S_C: /* C comment */
if(!elide){
fputc(ch, out);
}
if(slash == ch){
if(star == prev){
/* MARKER(("state 3 ==> 0 @ %d:%d\n", line, col)); */
/* Corner case which breaks this: */
/*/ <-- slash there */
/* That shows up twice in a piece of 3rd-party
code i use. */
/* And thus state3Col was introduced :/ */
if(col!=state3Col+2){
state = S_NONE;
elide = 0;
state3Col = -99;
}
}
}
break;
default:
assert(!"impossible!");
break;
}
if('\n' == ch){
++line;
col = 0;
state3Col = -99;
}
}
}
static void usage(char const *zAppName){
fprintf(stderr, "Strips C- and C++-style comments from stdin and sends "
"the results to stdout.\n");
fprintf(stderr, "Usage: %s [--keep-first|-k] < input > output\n", zAppName);
}
int main( int argc, char const * const * argv ){
int i;
for(i = 1; i < argc; ++i){
char const * zArg = argv[i];
while( '-'==*zArg ) ++zArg;
if( 0==strcmp(zArg,"k")
|| 0==strcmp(zArg,"keep-first") ){
++App.keepFirst;
}else{
usage(argv[0]);
return 1;
}
}
App.input = stdin;
App.output = stdout;
do_it_all();
return App.rc ? 1 : 0;
}