New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

deadunit-core

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

deadunit-core - npm Package Compare versions

Comparing version 5.0.11 to 5.0.12

test/deadlinkSourceOriginal.js

20

build.js
var fs = require("fs")
var path = require('path')
var child = require("child_process")

@@ -14,8 +15,7 @@ var webpack = require("webpack")

browserifyBuild(__dirname+"/test/deadunitTests.browser", 'deadunitTests.browser')
browserifyBuild(__dirname+"/test/inlineSourceMapTest", 'inlineSourceMapTest.browserified')
browserifyBuild(__dirname+"/test/deadlinkSourcemapPath", 'deadlinkSourcemapPath')
browserifyBuild(__dirname+"/test/deadlinkSourceOriginal", 'deadlinkSourceOriginal')
buildCoffeescriptFile(__dirname+"/test/sourceMapTest.coffee")
// the following generated files that has since been manually modified
// browserifyBuild(__dirname+"/test/inlineSourceMapTest.js", 'inlineSourceMapTest.browserified')
// browserifyBuild(__dirname+"/test/deadlinkSourcemapPath", 'deadlinkSourcemapPath')
// browserifyBuild(__dirname+"/test/deadlinkSourceOriginal", 'deadlinkSourceOriginal')
// webpack bundle

@@ -26,2 +26,12 @@

function buildCoffeescriptFile(script) {
console.log(require.resolve('coffee-script/bin/coffee'))
var c = child.spawn('node', [require.resolve('coffee-script/bin/coffee'), script, '--map'], {stdio: 'inherit'})
c.on('error', function(E) {
console.log("ahhhh "+E)
})
c.on('exit', function() {
console.log("done building "+script)
})
}

@@ -28,0 +38,0 @@ function browserifyBuild(entrypoint, globalName) {

@@ -568,6 +568,5 @@ "use strict";

column = mappedInfo.column
var sourceLines = mappedInfo.sourceLines
var multiLineSearch = !mappedInfo.usingOriginalFile // don't to a multi-line search if the source has been mapped (the file might not be javascript)
return getFunctionCallLines(mappedInfo.file, functionName, mappedInfo.line, multiLineSearch, warningHandler)
} else {

@@ -577,4 +576,8 @@ file = info.file

column = info.column
return getFunctionCallLines(file, functionName, line, true, warningHandler)
var sourceLines = undefined
var multiLineSearch = true
}
return getFunctionCallLines(sourceLines, file, functionName, line, multiLineSearch, warningHandler)
}).catch(function(e) {

@@ -604,5 +607,6 @@ warningHandler(e)

/* I don't think this is needed any longer, and probably isn't correct - this was working around an issue in webpack: See https://github.com/webpack/webpack/issues/559 and https://github.com/webpack/webpack/issues/238
if(sourceMapConsumer.sourceRoot !== null) {
sourceMapInfo.source = sourceMapInfo.source.replace(sourceMapConsumer.sourceRoot, '') // remove sourceRoot (todo: quesion: is this the right thing to do? See https://github.com/webpack/webpack/issues/238)
}
sourceMapInfo.source = sourceMapInfo.source.replace(sourceMapConsumer.sourceRoot, '') // remove sourceRoot
}*/

@@ -633,2 +637,8 @@ if(relative) {

if(file != undefined && sourceMapConsumer.sourcesContent != undefined) { // intentional single !=
var index = sourceMapConsumer.sources.indexOf(file)
var sourceLines = sourceMapConsumer.sourcesContent[index]
if(sourceLines !== undefined) sourceLines = sourceLines.split('\n')
}
return {

@@ -639,3 +649,4 @@ file: file,

column: column,
usingOriginalFile: originalFile
usingOriginalFile: originalFile,
sourceLines: sourceLines
}

@@ -646,4 +657,9 @@ }

// if multiLineSearch is true, it finds
function getFunctionCallLines(filePath, functionName, lineNumber, multiLineSearch, warningHandler) {
return options.getScriptSourceLines(filePath).catch(function(e) {
function getFunctionCallLines(sourcesContent, filePath, functionName, lineNumber, multiLineSearch, warningHandler) {
if(sourcesContent !== undefined) {
var source = Future(sourcesContent)
} else {
var source = options.getScriptSourceLines(filePath)
}
return source.catch(function(e) {
warningHandler(e)

@@ -650,0 +666,0 @@ return Future(undefined)

{"name":"deadunit-core",
"description": "The core for deadunit - a dead-simple nestable unit testing library for javascript in node.js and the browser.",
"keywords": ["unit", "test", "testing", "javascript", "node", "deadunit", "asynchronous"],
"version":"5.0.11",
"version":"5.0.12",
"dependencies":{

@@ -20,3 +20,4 @@ "async-future":"1.0.2",

"browserify": "",
"webpack": ""
"webpack": "",
"coffee-script":""
},

@@ -23,0 +24,0 @@ "author": "Billy Tetrud <bitetrudpublic@gmail.com> (https://github.com/fresheneesz/)",

@@ -308,2 +308,3 @@ `deadunitCore`

* 5.0.12 - adding support for pulling sources from the sourcemap (if the sourcemap has them)
* 5.0.10 - upgrading async futures, adding test case for the recursion issue, and bolstering "too much recursion" avoidance

@@ -310,0 +311,0 @@ * 5.0.9 - fixing too much recursion issue in the tests (affected firefox)

@@ -1,6 +0,4 @@

var root = typeof global !== "undefined" && global !== null ? global : window;
root.sourceMapTest4 = function() {
grobal.deadlinkSourcemapPath = function() {
this.ok(true)
throw new Error("deadlink sourcemap path error")
}
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.deadlinkSourcemapPath=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
(function (){
var root = typeof global !== "undefined" && global !== null ? global : window;
root.sourceMapTest4 = function() {
grobal.deadlinkSourcemapPath = function() {
this.ok(true)

@@ -10,6 +7,5 @@ throw new Error("deadlink sourcemap path error")

}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}]},{},[1])
//# sourceMappingURL=doesntExist.js.map
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyJEOlxcYmlsbHlzRmlsZVxcY29kZVxcamF2YXNjcmlwdFxcbm9kZWpzXFxtb2R1bGVzXFxkZWFkdW5pdENvcmVcXG5vZGVfbW9kdWxlc1xcYnJvd3NlcmlmeVxcbm9kZV9tb2R1bGVzXFxicm93c2VyLXBhY2tcXF9wcmVsdWRlLmpzIiwiRDovYmlsbHlzRmlsZS9jb2RlL2phdmFzY3JpcHQvbm9kZWpzL21vZHVsZXMvZGVhZHVuaXRDb3JlL3Rlc3QvZGVhZGxpbmtTb3VyY2VtYXBQYXRoLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiZ3JvYmFsLmRlYWRsaW5rU291cmNlbWFwUGF0aCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdGhpcy5vayh0cnVlKVxyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiZGVhZGxpbmsgc291cmNlbWFwIHBhdGggZXJyb3JcIilcclxufVxyXG4iXX0=
(1)
});
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.deadlinkSourceOriginal=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
(function (){
var root = typeof global !== "undefined" && global !== null ? global : window;
root.sourceMapTest5 = function() {
grobal.deadlinkSourceOriginal = function() {
this.ok(true)

@@ -10,6 +7,5 @@ throw new Error("deadlink source original error")

}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}]},{},[1])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyJGOlxcYmlsbHlzRmlsZVxcY29kZVxcamF2YXNjcmlwdFxcbm9kZWpzXFxkZWFkdW5pdENvcmVcXG5vZGVfbW9kdWxlc1xcYnJvd3NlcmlmeVxcbm9kZV9tb2R1bGVzXFxicm93c2VyLXBhY2tcXF9wcmVsdWRlLmpzIiwiRjovYmlsbHlzRmlsZS9jb2RlL2phdmFzY3JpcHQvbm9kZWpzL2RlYWR1bml0Q29yZS90ZXN0L2RlYWRsaW5rU291cmNlT3JpZ2luYWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciByb290ID0gdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWwgIT09IG51bGwgPyBnbG9iYWwgOiB3aW5kb3c7XHJcblxyXG5yb290LnNvdXJjZU1hcFRlc3Q1ID0gZnVuY3Rpb24oKSB7XHJcbiAgICB0aGlzLm9rKHRydWUpXHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJkZWFkbGluayBzb3VyY2Ugb3JpZ2luYWwgZXJyb3JcIilcclxufVxyXG5cbn0pLmNhbGwodGhpcyx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pIl19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyJEOlxcYmlsbHlzRmlsZVxcY29kZVxcamF2YXNjcmlwdFxcbm9kZWpzXFxtb2R1bGVzXFxkZWFkdW5pdENvcmVcXG5vZGVfbW9kdWxlc1xcYnJvd3NlcmlmeVxcbm9kZV9tb2R1bGVzXFxicm93c2VyLXBhY2tcXF9wcmVsdWRlLmpzIiwiRDovYmlsbHlzRmlsZS9jb2RlL2phdmFzY3JpcHQvbm9kZWpzL21vZHVsZXMvZGVhZHVuaXRDb3JlL3Rlc3QvZGVhZGxpbmtTb3VyY2VPcmlnaW5hbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsImdyb2JhbC5kZWFkbGlua1NvdXJjZU9yaWdpbmFsID0gZnVuY3Rpb24oKSB7XHJcbiAgICB0aGlzLm9rKHRydWUpXHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJkZWFkbGluayBzb3VyY2Ugb3JpZ2luYWwgZXJyb3JcIilcclxufVxyXG4iXX0=
(1)
});

@@ -34,3 +34,3 @@

var unittest = Unit.test(function() {
this.test('webpack source map file', window.sourceMapTest3)
this.test('webpack source map file', grobal.webpackTest)
}).events({

@@ -40,7 +40,11 @@ end: function(e) {

t.ok(results.results[0].results[0].line === 4)
t.ok(results.results[0].results[0].line === 2)
t.ok(results.results[0].results[0].sourceLines === 'this.ok(true)')
t.ok(results.results[0].exceptions.length === 1)
t.ok(results.results[0].exceptions[0].message === "webpack bundle error")
t.ok(results.results[0].exceptions[0].stack.match(/sourceMapTest3 \(.*webpackTest.js:5(:[0-9]+)?\)/) !== null, results.results[0].exceptions[0].stack)
var webpackExceptionLine = 3
t.ok(results.results[0].exceptions[0].stack.match(
new RegExp("webpackTest \\(.*webpackTest.js:"+webpackExceptionLine+"(:[0-9]+)?\\)")
) !== null,
results.results[0].exceptions[0].stack)
t.log(results.results[0].exceptions[0])

@@ -47,0 +51,0 @@

@@ -41,2 +41,5 @@ "use strict";

//*

@@ -262,6 +265,6 @@ this.test('simple success', function(t) {

if(testEnvironment === 'node') {
var subtest3line = 150
var subtest3line = 153
this.ok(subtest3.line === subtest3line, subtest3.line)
} else {
var subtest3line = 7920
var subtest3line = 7942
this.ok(subtest3.line === subtest3line, subtest3.line) // browserify bug causes sourcemap to not be found

@@ -771,6 +774,6 @@ }

var unittest = Unit.test(function() {
this.test('coffeescript file', global.sourceMapTest)
this.test('inline source map file', global.sourceMapTest2)
this.test('sourcemap file not found', global.sourceMapTest4)
this.test('original file not found', global.sourceMapTest5)
this.test('coffeescript file', global.sourceMapTest) // coffeescript sucks
this.test('inline source map file', grobal.inlineSourceMapTest)
this.test('sourcemap file not found', grobal.deadlinkSourcemapPath)
this.test('original file not found', grobal.deadlinkSourceOriginal)
}).events({

@@ -780,4 +783,4 @@ end: function(e) {

t.ok(results.results[0].results[0].line === 4)
t.ok(results.results[0].results[0].sourceLines === 'this.ok true')
t.eq(results.results[0].results[0].line , 4)
t.eq(results.results[0].results[0].sourceLines , 'this.ok true')

@@ -787,21 +790,32 @@ t.ok(results.results[0].results[1].results[0].line === 11) // in the original source it's 8, this tests turning off source map printing

t.ok(results.results[0].exceptions.length === 1)
t.ok(results.results[0].exceptions[0].message === 'sourcemap test error')
t.ok(results.results[0].exceptions[0].stack.match(/sourceMapTest \(.*sourceMapTest.coffee:10(:[0-9]+)?\)/) !== null, results.results[0].exceptions[0].stack)
t.eq(results.results[0].exceptions[0].message , 'sourcemap test error')
t.ok(results.results[0].exceptions[0].stack.match(
/sourceMapTest \(.*sourceMapTest.coffee:10(:[0-9]+)?\)/
) !== null,
results.results[0].exceptions[0].stack)
t.log(results.results[0].exceptions[0])
t.ok(results.results[1].results[0].line === 5) // IMPORTANT NOTE: the line *should* be 4, but looks like browserify messed this one up
t.ok(results.results[1].results[0].sourceLines === 'this.ok(true)')
t.eq(results.results[1].results[0].line , 3) // IMPORTANT NOTE: the line *should* be 2, but looks like browserify messed this one up
t.eq(results.results[1].results[0].sourceLines, 'this.ok(true)')
t.ok(results.results[2].results[0].line === 6)
t.eq(results.results[2].results[0].line , 3) // IMPORTANT NOTE: the line *should* be 2, but looks like browserify messed this one up
t.ok(results.results[2].results[0].sourceLines === 'this.ok(true)')
t.ok(results.results[2].exceptions.length === 1)
t.ok(results.results[2].exceptions[0].message === "deadlink sourcemap path error")
t.ok(results.results[2].exceptions[0].stack.match(/sourceMapTest4 \(.*deadlinkSourcemapPath.umd.js:7(:[0-9]+)?\)/) !== null, results.results[2].exceptions[0].stack)
var deadlinkSourceMapPath_line = 4
t.ok(results.results[2].exceptions[0].stack.match(
new RegExp("deadlinkSourcemapPath \\(.*deadlinkSourcemapPath.umd.js:"+deadlinkSourceMapPath_line+"(:[0-9]+)?\\)") // /deadlinkSourcemapPath \(.*deadlinkSourcemapPath.umd.js:7(:[0-9]+)?\)/
) !== null,
results.results[2].exceptions[0].stack)
t.log(results.results[2].exceptions[0])
t.ok(results.results[3].results[0].line === 6)
t.eq(results.results[3].results[0].line , 3) // IMPORTANT NOTE: the line *should* be 2, but looks like browserify messed this one up
t.ok(results.results[3].results[0].sourceLines === 'this.ok(true)')
t.ok(results.results[3].exceptions.length === 1)
t.ok(results.results[3].exceptions[0].message === "deadlink source original error")
t.ok(results.results[3].exceptions[0].stack.match(/sourceMapTest5 \(.*deadlinkSourceOriginal.umd.js:7(:[0-9]+)?\)/) !== null, results.results[3].exceptions[0].stack)
var deadlinkSourceOriginal_line = 4
t.ok(results.results[3].exceptions[0].stack.match(
new RegExp("deadlinkSourceOriginal \\(.*deadlinkSourceOriginal.umd.js:"+deadlinkSourceOriginal_line+"(:[0-9]+)?\\)") // /deadlinkSourceOriginal \(.*deadlinkSourceOriginal.umd.js:7(:[0-9]+)?\)/
) !== null,
results.results[3].exceptions[0].stack)
t.log(results.results[3].exceptions[0])

@@ -808,0 +822,0 @@ }

@@ -1,5 +0,3 @@

var root = typeof global !== "undefined" && global !== null ? global : window;
root.sourceMapTest2 = function() {
grobal.inlineSourceMapTest = function() {
this.ok(true)
}
"use strict";
global.grobal = {a:'mooo'} // global variable!!!!!
var OldDeadunit = require('deadunit')

@@ -10,3 +12,3 @@ var Unit = require('../deadunitCore.node')

// these two are required for the 'sourcemap' test, but need to be here because the files can't be built into the bundle (or the sourcemap comment will eff things up)
require('./inlineSourceMapTest.browserified.umd')
require('./inlineSourceMapTest.umd')
require('./sourceMapTest.js') // generated by coffeescript

@@ -13,0 +15,0 @@ require('./generated/webpackTest.js.bundle.js')

@@ -1,6 +0,4 @@

var root = typeof global !== "undefined" && global !== null ? global : window;
root.sourceMapTest3 = function() {
grobal.webpackTest = function() {
this.ok(true)
throw new Error("webpack bundle error")
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc